Search code examples
c#wpficonsmenuitemcontenttemplate

WPF MenuItem Icon only showing one instance of ContentControl template


I'm using a style to set the icon of menu items in a context menu, so that a different item is shown based on the sort of object the menu item relates to.

For now, I'm avoiding changing the item, and simply trying to place one icon (a puzzle piece) next to all menu items.

<!-- A pizzle-piece icon -->
<DataTemplate x:Key="DefaultComponentIconPath">
    <Path Data="{StaticResource PuzzlePieceGeometry}" Stroke="{DynamicResource PrimaryBrush}" StrokeThickness="1.8" Stretch="Uniform"/>
</DataTemplate>

<!-- The style applied to all menu items in the menu -->
<Style x:Key="ViewportMenuItemStyle" BasedOn="{StaticResource MenuItemBaseStyle}" TargetType="{x:Type MenuItem}">
    <Setter Property="Icon">
        <Setter.Value>
            <ContentControl ContentTemplate="{StaticResource DefaultComponentIconPath}"/>
        </Setter.Value>
    </Setter>
</Style>

<!-- This is needed because there are both MenuItems and Separators in my right-click menu, and if the above style targets a Separator, an error is thrown -->
<local:ViewportMenuItemStyleSelector x:Key="ViewportMenuItemStyleSelector" MenuItemStyle="{StaticResource ViewportMenuItemStyle}"/>

<!-- The style used for my special right-click menu -->
<Style BasedOn="{StaticResource ContextMenuBaseStyle}" TargetType="{x:Type local:ViewportContextMenu}">
    <Setter Property="ItemContainerStyleSelector" Value="{StaticResource ViewportMenuItemStyleSelector}"/>
</Style>

Instead of showing a puzzle piece next to all menu items, only one icon appears, always on the last menu item to have loaded. In fact, if I open a sub-menu, the icon will move to the last item in that sub-menu. There's clearly only one icon instance, being traded around. enter image description here

I'm using a ContentTemplate, so why is this happening?


Solution

  • To be able to reuse an element resource across the UI, you should set the x:Shared attribute of it to false. Try this:

    <local:ViewportMenuItemStyleSelector x:Shared="False" x:Key="ViewportMenuItemStyleSelector" 
         MenuItemStyle="{StaticResource ViewportMenuItemStyle}"/>