Introduction
This article explains a technique of attached behavior that I just used to define WPF adorners in XAML. The technique was based on the article by Ashley Davis explaining how to defining WPF Adorners in XAML, too. But I still want to go a step further. Some changes (some just in my like) and improvements are:
- Replace the defined Adorned Control with just a
static
behavior class
- Add a new member in the
AdornerPlacement enum
, namely Across
- Most importantly, add supports for multiple
Adorner
Child
The main class is MultiChildAdornerBehavior
which is a static
helper class containing some AttachedProperty
definitions. What is aimed to be adorned stays what it is. Just adding a few AttachedProperties
would make the whole thing fly. As for the FrameworkElementMultiChildAdorner
class, it is just a modification of Ashley’s gift.
I have included a simple project to accompany this article. And I think the sample is enough to demonstrate the reusability of this MultiChildAdornerBehavior
that is described in this article. Hope some of you may appreciate it.
Assumed Knowledge
It is assumed that you already know C# and have a basic knowledge of WPF and XAML. And knowing some of the basic principles of WPF programs would be helpful.
Background
Recently, I was asked to develop a tiny drawing program for some reason. As I just started to learn WPF, I decided to try myself out. In the drawing program, UI elements need to be dragged around and resizable too, in runtime. I searched this web and found Ashley’ s article is in my need but still need to be expanded, mainly in that its adorner only holds on Framework Element child and is not easy to position accurately if you just contain multiple adorner parts in one big adorner content. Also, some other tiny aspects can also be improved just in my way.
Using the Code
Suppose we want to adorn a Rectangle with 4 adorner children on each side and with AdornerPlacement
set to different value, as the second row in the above picture. First, we just define a basic normal Rectangle
in XAML like this:
<Rectangle Stroke="Blue" Fill="Transparent"
Width="50"
Height="50"/>
Since adorners need to be added to this silly Rectangle
, we just add a line using AttachedProperty
. And it becomes:
<Rectangle Stroke="Blue"
pc:MultiChildAdornerBehavior.IsAdornerVisible="True"
Fill="Transparent"
Width="50"
Height="50">
And where are the adorner children? Just add another AttachedProperty
, a not so small one:
<Rectangle Stroke="Blue"
pc:MultiChildAdornerBehavior.IsAdornerVisible="True"
Fill="Transparent"
Width="50"
Height="50">
<pc:MultiChildAdornerBehavior.AdornerChildren>
<x:Array Type="FrameworkElement">
<Ellipse
Width="15"
Height="15"
Stroke="Green"
HorizontalAlignment="Left"
pc:MultiChildAdornerBehavior.HorizontalPlacement="Inside"/>
<Ellipse
Width="15"
Height="15"
Stroke="Red"
HorizontalAlignment="Right"/>
<Ellipse
Width="15"
Height="15"
Stroke="Brown"
VerticalAlignment="Top"/>
<Ellipse
Width="15"
Height="15"
Fill="Brown"
VerticalAlignment="Bottom"
pc:MultiChildAdornerBehavior.VerticalPlacement="Outside"/>
</x:Array>
</pc:MultiChildAdornerBehavior.AdornerChildren>
</Rectangle>
Notice we also use some kind of attached property to define the adorner children. In Ashley’s solution, this property is set on the adorned content, which meant it only can have one value although multiple adorner parts are held up in some way. That is not too satisfactory if I want to adopt it in my simple task.
And that’s all. The resulted effect is just what I wanted. Each Adorner child is treated separately when they are added to the FrameworkElementMultiChildAdorner
and arranged by FrameworkElementMultiChildAdorner
. The code is simple and self-explainatory, and I am still too lazy.
Actually I am so lazy that I cut down much of Ashley’s solution. Those about animation added to the implementation of AdornerContent
are just too much for me.
I hope my tiny work will not let you down!
Points of Interest
Nothing, Nothing, Nothing
History
- 1st November, 2010: Initial post