Use any DataTemplate as an Adorner in WPF






4.72/5 (9 votes)
This article explains a simpler way of attaching adorners by using a WPF behavior class.
Introduction
Adorners are great and sometimes you want to quickly put some adorners up with ease. All samples today usually include custom building adorners with code, or some other class.
This article explains a simpler way of attaching adorners by using a behavior class. The attached example was created with Expression Blend 4.0 but you can open it in Visual Studio 2010.
All code described here is in the attached project.
Find the final screen below. Adorners are composed of visual elements via the DataTemplate
.
Using the code
The code is quite simple. First you need to ensure the item you want to adorn contains an Adorner layer, otherwise CaAdornerBehavior
will throw a null exception.
Use an AdornerDecorator
to add the adorner layer. The XAML sample follows:
<Grid x:Name="LayoutRoot">
<AdornerDecorator Width="250" Height="250">
<ed:Arc x:Name="arc">
: : : : :
: : : : :
</ed:Arc>
</AdornerDecorator>
</Grid>
Copy the file CaAdornerBehavior.cs to your project folder and include in the project. This file will compile as a behavior. It will appear in Blend behavior assets:
Here, we’ll go over the Blend designer to integrate the behavior properties.
- Notice the behavior part of the
Arc
object. This associates the behavior withArc
. Using the designer, you can associate the behavior with other objects. - The behavior contains two event properties:
ShowAdornerCommand
andHideAdornerCommand
. These bindings allow the user to control showing or hiding the template adorner. - Notice the
AdornerTemplate
property. Here the behavior accepts theDataTemplate
that will be shown as the adorner. TheDataTemplate
is internally hosted as aContentTemplate
of aContentControl
in the Behavior. - The Adorner
DataTemplate
. It is a standardDataTemplate
so you can include any visual element.
XAML code
The Adorner DataTemplate
is very straightforward. It includes some icons aligned accordingly.
<Window.Resources>
<DropShadowEffect x:Key="BlurEffectStyle" …/>
<!-- Template used in Adorner -->
<DataTemplate x:Key="AdornerDataTemplate">
<Grid>
<StackPanel Orientation="Horizontal">
<Image Height="32" Width="32"
Source="Mail-add.png"/>
<Image Height="32"
Source="Paper-pencil.png" Width="32"/>
<Button Style="{DynamicResource SimpleButton}"
Width="32" Height="32">
<Image Height="Auto"
Source="Exclamation.png"
Stretch="Fill"/>
</Button>
</StackPanel>
<Image Source="Pencil.png"
Width="32" Height="32"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"/>
</Grid>
</DataTemplate>
</Window.Resources>
Using the adorner behavior is also very straightforward.
<Custom:Interaction.Behaviors>
<CaControlTestApp:CaAdornerBehavior
AdornerTemplate="{DynamicResource AdornerDataTemplate}">
<Custom:Interaction.Triggers>
<Custom:EventTrigger SourceName="arc"
EventName="MouseEnter">
<Custom:InvokeCommandAction
CommandName="ShowAdornerCommand"/>
</Custom:EventTrigger>
<Custom:EventTrigger SourceName="arc"
EventName="MouseLeave">
<Custom:InvokeCommandAction
CommandName="HideAdornerCommand"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</CaControlTestApp:CaAdornerBehavior>
</Custom:Interaction.Behaviors>
Notice that we have event triggers to show/hide the adorner to the parent's MouseEvents. You can use any other trigger to show it. A DataTrigger
, and others, will also work.
History
- 19 Oct 2011: First version.
- 18 Nov 2011: Sample code updated. The behavior class was not properly binding. This was fixed to bind to the adorned UI element data context.