Adorner en WPF

Los Adorner en WPF son simple decoradores de UIElements, esta clase Adorner es un FrameWorkElement que se “enlaza” al control de usuario que se quiere adornar, realmente es un adorno visual, al cual se puede añadir funcionalidad. Para que se entienda mejor en Office 2007 podría ser un Adorner la mini Toolbar que aparece cuando seleccionamos una palabra

WordMiniToolbar

Un Adorner nos va a permitir Añadir visual feedback a un control, o notificaciones al usuario o… lo que diseñéis.

Vamos a  construir un ejemplo para que se vea mejor, este ejemplo es en un TextBox vamos ha hacer que aparezca por encima un botón con la imagen de Internet Explorer, este botón aparecerá si el texto comienza por “http://”, no lo hare con expresiones regulares ya que no es el objetivo.

Comencemos, creamos una clase que llamaremos TextBoxAdorner, esta clase si queremos que sea un Adorner deberá heredar de la clase abstracta Adorner que nos obliga a crear un constructor con parámetros de esta manera

 

 public TextBoxAdorner(UIElement adornerelement)
           : base(adornerelement)

Como mínimo tiene que tener un parámetro que es el objeto (UIElement) que vamos a adornar, podrá ser un constructor con los parámetros que queráis pero como mínimo tendrá esta firma.

Dentro del constructor almacenamos el elemento a adornar y lo añadimos al árbol visual del Adorner en este caso el boton

 

VisualCollection visualChildren;
        Button btnInternet = new Button();

        public TextBoxAdorner(UIElement adornerelement)
            : base(adornerelement)
        {
            visualChildren = new VisualCollection(this);

            CreateButton();
        }

        private void CreateButton()
        {
            btnInternet.Height = 20;
            btnInternet.Width = 20;
            btnInternet.Background = new ImageBrush(new BitmapImage(
                    new Uri(@"imgExplorer.jpg", UriKind.Relative)));
            btnInternet.Click += new RoutedEventHandler(btnInternet_Click);
            visualChildren.Add(btnInternet);
        }

Si queremos que el elemento pasado en AddVisualChild sea visible debemos sobrescribir VisualChildrenCount y GetVisualChild() para

devolver el UIElement que se ha añadido al árbol visual

  protected override int VisualChildrenCount { get { return visualChildren.Count; } }
        protected override Visual GetVisualChild(int index) { return visualChildren[index]; }

 

El siguiente paso es sobrescribir ArrangeOverride para dibujar nuestro decorador en el elemento a adornar

 

 protected override Size ArrangeOverride(Size finalSize)
        {
            // desiredWidth and desiredHeight are the width and height of the element that's being adorned.
            double desiredWidth = AdornedElement.DesiredSize.Width;
            double desiredHeight = AdornedElement.DesiredSize.Height;

            double adornerWidth = this.DesiredSize.Width;
            double adornerHeight = this.DesiredSize.Height;
            btnInternet.Arrange(new Rect(adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));


            return finalSize;
        }

En este evento indicamos donde dibujamos el adorner

Para utilizar el Adorner que hemos creado es tan sencillo como

private Adorner addSymbolAdorner;

        public Window1()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Window1_Loaded);
        }

        void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            addSymbolAdorner = new TextBoxAdorner(TestTextBox);
            AdornerLayer.GetAdornerLayer(TestTextBox).Add(addSymbolAdorner);
        }

El Adorner que hemos creado es muy sencillo, tenéis aquí la aplicación completa para que podáis verla con tranquilidad

 

Tenéis muchos mas ejemplos de Adorner, uno muy interesante es de  aquí de Denis Vuyka, también están los ejemplos de del SDK

2 comentarios sobre “Adorner en WPF”

  1. Caray!!! no sabia de este tipo de elementos en la interface, y eso que el otro día aprobé la certificación de MCTS en Windows Presentation Foundation.

    Gracias por este post.

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *