Información general sobre adornos

Los Adorner son un tipo especial de FrameworkElement, que se utiliza para proporcionar indicaciones visuales a un usuario. Entre otros usos, los Adorners se pueden utilizar para agregar controladores funcionales a los elementos o proporcionar información de estado sobre un control.

Acerca de Adorners

Un control Adorner es un elemento FrameworkElement personalizado que está enlazado a UIElement. Los Adorner se representan en AdornerLayer, que es una superficie de representación que siempre se encuentra encima del elemento adornado o de una colección de elementos adornados. La representación de un adorno es independiente de la representación del UIElement al que está enlazado el adorno. Un adorno se suele colocar respecto al elemento al que se enlaza, utilizando el origen de coordenadas 2D estándar situado en la parte superior izquierda del elemento adornado.

Algunas aplicaciones comunes de adornos son:

  • Agregar controladores funcionales a un UIElement, que permiten al usuario manipular el elemento de alguna manera (cambiar su tamaño o posición, girarlo, etc.).
  • Proporcionar comentarios visuales para indicar diversos estados, o en respuesta a distintos eventos.
  • Superponer etiquetas contextuales visuales en un UIElement.
  • Invalidar o enmascarar visualmente la totalidad o parte de un UIElement.

Windows Presentation Foundation (WPF) proporciona un marco básico para adornar elementos visuales. En la tabla siguiente se muestra una lista de los tipos principales utilizados al adornar objetos y su finalidad. A continuación se presentan varios ejemplos de uso:

Clase Descripción
Adorner Una clase base abstracta de la que heredan todas las implementaciones de adornos contextuales concretas.
AdornerLayer Una clase que representa una capa de representación para los adornos de uno o más elementos adornados.
AdornerDecorator Una clase que permite asociar una capa de adornos a una colección de elementos.

Implementación de un adorno personalizado

El marco de adornos que proporciona Windows Presentation Foundation (WPF) está diseñado principalmente para admitir la creación de adornos personalizados. Un adorno personalizado se crea implementando una clase que hereda de la clase Adornerabstracta.

Nota

El elemento primario de un objeto Adorner es AdornerLayer, que representa Adorner, no el elemento adornado.

En el ejemplo siguiente se muestra una clase que implementa un adorno simple. El adorno del ejemplo se limita adornar las esquinas de UIElement con círculos.

// Adorners must subclass the abstract base class Adorner.
public class SimpleCircleAdorner : Adorner
{
  // Be sure to call the base class constructor.
  public SimpleCircleAdorner(UIElement adornedElement)
    : base(adornedElement)
  {
  }

  // A common way to implement an adorner's rendering behavior is to override the OnRender
  // method, which is called by the layout system as part of a rendering pass.
  protected override void OnRender(DrawingContext drawingContext)
  {
    Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);

    // Some arbitrary drawing implements.
    SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
    renderBrush.Opacity = 0.2;
    Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
    double renderRadius = 5.0;

    // Draw a circle at each corner.
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
  }
}
Public Class SimpleCircleAdorner
    Inherits Adorner
    Sub New(ByVal adornedElement As UIElement)
        MyBase.New(adornedElement)
    End Sub

    Protected Overrides Sub OnRender(ByVal drawingContext As System.Windows.Media.DrawingContext)
        MyBase.OnRender(drawingContext)
        Dim adornedElementRect As New Rect(AdornedElement.DesiredSize)
        Dim renderBrush As New SolidColorBrush(Colors.Green)
        renderBrush.Opacity = 0.2
        Dim renderPen As New Pen(New SolidColorBrush(Colors.Navy), 1.5)
        Dim renderRadius As Double
        renderRadius = 5.0

        'Draw a circle at each corner.
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius)
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius)
    End Sub
End Class

En la ilustración siguiente se muestra SimpleCircleAdorner aplicado a un control TextBox:

Captura de pantalla que muestra un cuadro de texto adornado.

Comportamiento de representación de los adornos

Es importante tener en cuenta que los adornos no incluyen ningún comportamiento de representación inherente; asegurarse de que un adorno se representa es responsabilidad del implementador del adorno. Una manera común de implementar el comportamiento de representación es invalidar el método OnRender y utilizar uno o más objetos DrawingContext para representar los elementos visuales del adorno según sea necesario (como se muestra en el ejemplo anterior).

Nota

Todo aquello que se coloca en la capa de los adornos se representa encima del resto de estilos que se han establecido. En otras palabras, los adornos siempre están visualmente encima y no pueden invalidar utilizando el orden z.

Eventos y pruebas de posicionamiento

Los adornos reciben eventos de entrada exactamente igual que cualquier otro elemento FrameworkElement. Dado que un adorno siempre tiene un orden z más alto que el elemento al que adorna, dicho adorno recibe los eventos de entrada (como Drop o MouseMove) que podrían estar pensados para el elemento adornado subyacente. Un adorno puede realizar escuchas para ciertos eventos de entrada y pasárselos al elemento adornado subyacente volviendo a provocar el evento.

Para habilitar las pruebas de posicionamiento indirectas de los elementos que se encuentran debajo de un adorno, establezca la propiedad IsHitTestVisible de la prueba de posicionamiento en false. Para más información acerca de las pruebas de posicionamiento, consulte Hit Testing in the Visual Layer (Pruebas de posicionamiento en la capa visual).

Adorno de un solo elemento de la interfaz de usuario

Para enlazar un adorno a un elemento UIElement determinado, siga estos pasos:

  1. Llame al método estático GetAdornerLayer para obtener un objeto AdornerLayer para el elemento UIElement que se va a adornar. GetAdornerLayer recorre el árbol visual en sentido ascendente, empezando por el elemento UIElement especificado, y devuelve la primera capa de adornos que encuentra. (Si no se encuentra ninguna capa de adornos, el método devuelve null).

  2. Llame al método Add para enlazar el adorno al elemento UIElement de destino.

En el ejemplo siguiente se enlaza el adorno SimpleCircleAdorner (mostrado anteriormente) a un control TextBox denominado myTextBox:

myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))

Nota

En la actualidad, no se admite el uso de lenguaje XAML para enlazar un adorno a otro elemento.

Adornamiento de elementos secundarios de un panel

Para enlazar un adorno a los elementos secundarios de un control Panel, siga estos pasos:

  1. Llame al método staticGetAdornerLayer para buscar una capa de adornos del elemento cuyos elementos secundarios desea adornar.

  2. Enumere los elementos secundarios del elemento principal y llame al método Add para enlazar un adorno a cada elemento secundario.

En el ejemplo siguiente se enlaza el adorno SimpleCircleAdorner (mostrado anteriormente) a los elementos secundarios de un control StackPanel denominado myStackPanel:

foreach (UIElement toAdorn in myStackPanel.Children)
  myAdornerLayer.Add(new SimpleCircleAdorner(toAdorn));
For Each toAdorn As UIElement In myStackPanel.Children
    myAdornerLayer.Add(New SimpleCircleAdorner(toAdorn))
Next

Vea también