Introduction: You have a collection of shapes (or other elements), and you want to decorate each shape with one or more decoration, such as text.
Solution
Actually, there are several solutions. Some are straight forward, and some are more complex but flexible. I chose to describe a flexible way in which you don’t have to touch your visual tree directly from XAML. You just need to add decorations programmatically, whenever you liked to.
<Canvas x:Name="_shapes">
<Rectangle local:TextShapeDecoration.Anchor="0, -20" local:TextShapeDecoration.Text="Rectangle"
Width="80"
Height="48"
Canvas.Left="56"
Canvas.Top="56"
Fill="{DynamicResource RectBrush}"/> ...
</Canvas>
private void Button_Click(object sender, RoutedEventArgs e)
{
AdornerLayer textLayer = AdornerLayer.GetAdornerLayer(_shapes);
if (textLayer == null)
{
MessageBox.Show("No adorner layer was found.");
return;
}
TextShapeDecoration.SetAnchor(_circle, new Point(_circle.ActualWidth, _circle.ActualHeight / 2));
TextShapeDecoration.SetAnchor(_line, new Point(_line.ActualWidth / 2, _line.ActualHeight));
TextShapeDecoration.SetAnchor(_triangle, new Point(-_triangle.ActualWidth, _triangle.ActualHeight / 2));
foreach (Shape shape in _shapes.Children)
{
TextShapeDecoration textDecoration = new TextShapeDecoration(shape);
textLayer.Add(textDecoration);
}
}
As you can see, I'm using WPF AdornerLayer which represents the decoration layer. Whenver you like to have a decoration on your shape, simply create an instance of the custom TextShapeDecoration (Adorner), set attached properies (may already set from XAML), and add it to the decoration layer.
Download the code from here.