Windows .NET WPF orders their controls in a visual tree, and this tree has the restraint that every element can only have one parent. This can trip you when define a control as a resource, and then reuse it from the item template of a container. You will see the control exactly once in the list. So never do this in your XAML:
1 2 3 4 5 6 7 8 9 10 11 12 |
<Window> <Window.Resources> <Rectangle Width="16" Height="16" Fill="Green" x:Key="MyIcon"/> </Window.Resources> <ListBox> <ListBox.ItemTemplate> <DataTemplate> <Button Content={StaticResource MyIcon}/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window> |
Instead either use templates, with DataTemplate
or ControlTemplate
, or define a VisualBrush
for reuse. The better performance for icons and similar uses is with a visual brush, as it is one item that can be reused and is optimized for painting. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<Window> <Window.Resources> <Style x:Key="IconGreenStyle" TargetType="Rectangle"> <Setter Property="Width" Value="16"/> <Setter Property="Height" Value="16"/> <Setter Property="Fill"> <Setter.Value> <VisualBrush> <VisualBrush.Visual> <Rectangle Width="16" Height="16" Fill="Green"/> </VisualBrush.Visual> </VisualBrush> </Setter.Value> </Setter> </Style> </Window.Resources> <Rectangle Style="{StaticResource IconGreenStyle}"/> </Window> |
The alternative with ControlTemplate
initiates more, but is more compact to describe:
1 2 3 4 5 6 7 8 |
<Window> <Window.Resources> <ControlTemplate TargetType="Control" x:Key="IconGreenTemplate"> <Rectangle Width="16" Height="16" Fill="Green"/> </ControlTemplate> </Window.Resources> <Control Template="{StaticResource IconGreenTemplate}"/> </Window> |
I ran into these problems when I naively tried to use the Visual Studio Image Library for some basic icons for my app. All of their icons are defined as a Rectangle
, so these techniques are useful if you want to use them inside of lists.