-
Notifications
You must be signed in to change notification settings - Fork 51
UPF Adorners
Ultraviolet Framework 1.3 added support for adorners, which are a special type of element that visually decorate other elements.
New adorners must inherit from the Adorner
abstract class found in the Ultraviolet.Presentation.Documents
namespace.
For the most part, adorners are defined like any other UPF element, as they ultimately derive from the FrameworkElement
class. The example below is an adorner which draws four colored boxes at the corners of the adorned element.
public class ExampleBoxesAdorner : Adorner
{
const Double FullBoxSize = 16;
const Double HalfBoxSize = FullBoxSize / 2;
public ExampleBoxesAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
protected override void OnDrawing(UltravioletTime time, DrawingContext dc)
{
DrawBlank(dc, new RectangleD(-HalfBoxSize, -HalfBoxSize, FullBoxSize, FullBoxSize), Color.Red);
DrawBlank(dc, new RectangleD(AdornedElement.RenderSize.Width - HalfBoxSize, -HalfBoxSize, FullBoxSize, FullBoxSize), Color.Lime);
DrawBlank(dc, new RectangleD(-8, AdornedElement.RenderSize.Height - HalfBoxSize, FullBoxSize, FullBoxSize), Color.Blue);
DrawBlank(dc, new RectangleD(AdornedElement.RenderSize.Width - HalfBoxSize, AdornedElement.RenderSize.Height - HalfBoxSize, FullBoxSize, FullBoxSize), Color.Magenta);
base.OnDrawing(time, dc);
}
protected override RectangleD CalculateVisualBounds()
{
var bounds = AdornedElement.VisualBounds;
RectangleD.Inflate(ref bounds, HalfBoxSize, HalfBoxSize, out bounds);
return bounds;
}
}
The AdornedElement
property provides a reference to the element being adorned by this adorner instance. Here, we use it to calculate the positioning of our four boxes so that they are centered on the corners of the adorned element's visual bounding box.
Also, take note of the CalculateVisualBounds()
method. Our example adorner renders outside of the usual bounds of the adorned element, so we need to inform UPF of this fact in order to avoid being improperly clipped. If the adorner does not render outside of the adorned element's visual bounds, it is not necessary to override this method.
Adorners are added programatically by attaching instances of Adorner
to adorner layers.
Adorner layers are used to specify where adorners appear to reside within the visual tree; adorners associated with a particular layer will be rendered above any elements below that layer in the tree. Every view has an adorner layer at its root, and additional adorner layers can be added to a view by wrapping an element with an instance of the AdornerDecorator
container element.
<AdornerDecorator>
<Grid>
<!-- etc -->
</Grid>
</AdornerDecorator>
The static GetAdornerLayer()
method defined on the AdornerLayer
class will walk up the visual tree starting at the specified element and return the first adorner layer that it finds. Once you have that, you can use the Add()
method to add an adorner to the layer.
// Given that "btn" is a reference to an element...
var adornerLayer = AdornerLayer.GetAdornerLayer(btn);
adornerLayer.Add(new ExampleBoxesAdorner(btn));
- Contributing
- Dependencies
- Basic Concepts
- First Look- Platform
- First Look- Graphics
- First Look- Audio
- First Look- Input
- First Look- Content
- First Look- UI
- sRGB Color
- Customizing SpriteBatch
- Creating Fonts
- Creating Effects
- Creating Glyph Shaders
- FreeType2 Fonts
- Rendering 3D Models