Reputation: 18789
So I have a Context Menu
And a MenuItem
in it which breaks out into a list of names:
<ContextMenu>
<MenuItem Header="Set As Default For" ItemsSource="{Binding Source={StaticResource Names}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value={Binding Name}/>
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}, Path=DataContext.DoSomething}" />
<Setter Property="CommandParameter" Value="{Binding }" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
Now the above code works file and displays my list of names. Now I would like to add an Icon next to each Name using a Pack URI.. So from this question I can see the best way to do it is to template the Header
so I tried that first like the question
<ContextMenu>
<MenuItem Header="Set As Default For" ItemsSource="{Binding Source={StaticResource Names}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header">
<Setter.Value>
<StackPanel>
<Image Width="20" Height="20" Source="/MyProj;component/Resources/MyImg.png" />
<ContentPresenter Content="{Binding Name}" />
</StackPanel>
</Setter.Value>
</Setter>
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}, Path=DataContext.DoSomething}" />
<Setter Property="CommandParameter" Value="{Binding }" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
but this gave me the error:
Specified element is already the logical child of another element. Disconnect it first.
So I after some research I tried:
<ContextMenu>
<MenuItem Header="Set As Default For" ItemsSource="{Binding Source={StaticResource Names}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Image Width="20" Height="20" Source="/MyProj;component/Resources/MyImg.png" />
<ContentPresenter Content="{Binding Name}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}, Path=DataContext.DoSomething}" />
<Setter Property="CommandParameter" Value="{Binding }" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
But now all my names are ControlTemplate and no icon is displayed...
How do I add an icon to a Context Menu's Menu Item through ItemContainerStyle?
EDIT
I've tried:
<Setter Property="Header" Value="{Binding Name}"/>
<Setter Property="Icon">
<Setter.Value>
<Image Width="20" Height="20" Source="/MyProj;component/Resources/MyImg.png" />
</Setter.Value>
</Setter>
And I get an icon rendering but only for the last item in my menu?
Upvotes: 9
Views: 6418
Reputation: 33364
The problem is that you cannot use one visual in more then one place. You can do it either by using HeaderTemplate
instead of Header
, but use DataTemplate
instead of ControlTemplate
<Style TargetType="MenuItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<Image Width="20" Height="20" Source="/MyProj;component/Resources/MyImg.png" />
<ContentPresenter Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<!-- other setters -->
</Style>
Note that this solution will put icon in the content part of MenuItem
, not the icon. Another solution is to set Icon
property of MenuItem
as another Setter
but in this case Image
needs to
be separate Resource
with x:Shared
set to false otherwise you'll end up with the same problem where only last item has an icon.
<ContextMenu>
<ContextMenu.Resources>
<Image Width="20" Height="20" Source="/MyProj;component/Resources/MyImg.png" x:Key="myMenuIcon" x:Shared="False" />
</ContextMenu.Resources>
<MenuItem Header="Set As Default For" ItemsSource="{Binding Source={StaticResource Names}}">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Name}"/>
<Setter Property="Icon" Value="{StaticResource myMenuIcon}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
Upvotes: 13