As I have mentioned at the end of the previous post today I will show you how to create a generic adorner, which will allow you to decorate a single element  multiple times at different positions. At the end we will be able to create something that looks like this:

To achieve this we will need a way to say that we want to position the adorner at the different corners of the element as well as to specify whether we want to be inside or outside (vertically or horizontally) of the element. Let's create some enumeration types that will serve for this purpose. Introducing AdornerPosition and AdornerPlacement enums.

{

Unspecified = 0,

TopLeft = 1,

TopCenter = 2,

TopRight = 3,

MiddleLeft = 4,

MiddleCenter = 5,

MiddleRight = 6,

BottomLeft = 7,

BottomCenter = 8,

BottomRight = 9

}

{

Unspecified = 0,

In = 1,

OutHorizontally = 2,

OutVertically = 3

}

Each of the enums' values speak for it self, but for clarity here is a diagram that illustrates them:

The final piece is to implement the ArrangeOverride() method of the Adorner class. It looks like this:

protected override Size ArrangeOverride( Size finalSize )

{

if ( adorningElement != null )

{

int pos = (int) position - 1;

adorningPoint.X = ( ( ( pos % 3 ) / 2d ) * adorneredElementRect.Width )

- ( ( ( pos % 3 ) / 2d ) * adorningElementRect.Width );

adorningPoint.Y = ( ( ( pos / 3 ) / 2d ) * adorneredElementRect.Height )

- ( ( ( pos / 3 ) / 2d ) * adorningElementRect.Height );

if ( placement == AdornerPlacement.OutHorizontally )

{

switch ( pos % 3 )

{

default :

case 1 :

{

//center column do nothing

break;

}

case 0 :

{

break;

}

case 2 :

{

break;

}

}

}

else if ( placement == AdornerPlacement.OutVertically )

{

switch ( pos / 3 )

{

default :

case 1 :

{

//center row do nothing

break;

}

case 0 :

{

break;

}

case 2 :

{

break;

}

}

}

}

return finalSize;

}