Adorners are a special type of FrameworkElement, used to provide visual cues to a user. Among other uses, Adorners can be used to add functional handles to elements or provide state information about a control.
This topic contains the following sections.
An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements. Rendering of an adorner is independent from rendering of the UIElement that the adorner is bound to. An adorner is typically positioned relative to the element to which it is bound, using the standard 2-D coordinate origin located at the upper-left of the adorned element.
Common applications for adorners include:
Adding functional handles to a UIElement that enable a user to manipulate the element in some way (resize, rotate, reposition, etc.).
Provide visual feedback to indicate various states, or in response to various events.
Overlay visual decorations on a UIElement.
Visually mask or override part or all of a UIElement.
Windows Presentation Foundation (WPF) provides a basic framework for adorning visual elements. The following table lists the primary types used when adorning objects, and their purpose. Several usage examples follow.
The adorners framework provided by Windows Presentation Foundation (WPF) is intended primarily to support the creation of custom adorners. A custom adorner is created by implementing a class that inherits from the abstract Adorner class.
The following example shows a class that implements a simple adorner. The example adorner simply adorns the corners of a UIElement with circles.
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
The following image shows the SimpleCircleAdorner applied to a TextBox.
It is important to note that adorners do not include any inherent rendering behavior; ensuring that an adorner renders is the responsibility of the adorner implementer. A common way of implementing rendering behavior is to override the OnRender method and use one or more DrawingContext objects to render the adorner's visuals as needed (as shown in the example above).
Anything placed in the adorner layer is rendered on top of the rest of any styles you have set. In other words, adorners are always visually on top and cannot be overridden using z-order.
Adorners receive input events just like any other FrameworkElement. Because an adorner always has a higher z-order than the element it adorns, the adorner receives input events (such as Drop or MouseMove) that may be intended for the underlying adorned element. An adorner can listen for certain input events and pass these on to the underlying adorned element by re-raising the event.
To enable pass-through hit testing of elements under an adorner, set the hit test IsHitTestVisible property to false on the adorner. For more information about hit testing, see
To bind an adorner to a particular UIElement, follow these steps:
Call the static method GetAdornerLayer to get an AdornerLayer object for the UIElement to be adorned. GetAdornerLayer walks up the visual tree, starting at the specified UIElement, and returns the first adorner layer it finds. (If no adorner layers are found, the method returns null.)
The following example binds a SimpleCircleAdorner (shown above) to a TextBox named myTextBox.
Using Extensible Application Markup Language (XAML) to bind an adorner to another element is currently not supported.
To bind an adorner to the children of a Panel, follow these steps:
Call the static method GetAdornerLayer to find an adorner layer for the element whose children are to be adorned.
Enumerate through the children of the parent element and call the Add method to bind an adorner to each child element.
The following example binds a SimpleCircleAdorner (shown above) to the children of a StackPanel named myStackPanel.