This is a mirror of official site: http://jasper-net.blogspot.com/

Adorners in WPF

| Tuesday, March 1, 2011
What is an Adorner?
In WPF, an Adorner is special FrameworkElement that can be bounded to UIElement to allow user manipulate that element. Under manipulating we mean:
Adding functional handles to a UIElement that enable 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 whole UIElement.

WPF does not provide concrete adorners but it does provide the basic infrastructure. That means that you need to write your own special Adorner class.

A base infrastructure consists of next classes:

Adorner
This is a base Adorner from which you will need to subclass.

AdornerLayer
The AdornerLayer can be considered as a plane in which the Adorners are drawn.

AdornerDecorator
Defines the location in visual tree of an AdornerLayer. Window class already has it in the visual tree. It adds the default adorner layer above all other controls in the window.

Adorning a Single UIElement
To bind an adorner to a particular UIElement, follow these steps:

  1. Call the static method GetAdornerLayer of the AdornerLayer class 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 found. (If no adorner layers are found, the method returns null.)
  2. Create new instance of the adorner you need and pass it the instance of the UIElement you need to adorn.
  3. Call the Add method of the AdornerLayer, and pass it your new-ly created adorner to bind it to the target UIElement.

The following example binds  SomeAdorner (our own Adorner) to a TextBox named myTextBox.

myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SomeAdorner(myTextBox));

Adorning the Children of a Panel

To bind an adorner to the children of a Panel, follow these steps:
1. Call the static method GetAdornerLayer to find an adorner layer for the element children of which are to be adorned.
2. Enumerate the children of the parent element and call the Add method to bind an adorner to each child element.

The following example binds a SomeAdorner (our own Adorne) to the children of a StackPanel named myStackPanel.


foreach (UIElement toAdorn in myStackPanel.Children) myAdornerLayer.Add(new SomeAdorner(toAdorn));

Rendering
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 adorner is independent of rendering  UIElement the adorner is bound to. An adorner is typically positioned relatively to the element to which it is bound, using the standard 2-D coordinate origin located at the upper-left of the adorned element. Anything placed in the adorner layer is rendered on top of the rest visual elements. In other words, adorners are always visually on top and cannot be overridden using z-order.
It is important to note that adorners do not include any inherent rendering behavior (by default Adorner class does not render anything), ensuring that an adorner's rendering is the responsibility of the adorner's implementer.

This means that the adorner's rendering should be implemented by:

Overriding the OnRenderSizeChanged method and drawing adorner's visual content using the DrawingContext object methods.

Providing a visual children collection. (In this case you should override GetVisualChild method and VisualChildrenCount property)

The following examples accordingly show these approaches.

The first example adorner simply adorns the corners of a UIElement with circles.

Read more: Artfulbits

Posted via email from Jasper-net

0 comments: