使用 ItemContainerStyle 时如何在 ContextMenu 的 MenuItem 中设置图标
How to set an Icon in a ContextMenu's MenuItem when using ItemContainerStyle
所以我有一个 Context Menu
和一个 MenuItem
在里面,它分成一个名字列表:
<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>
现在上面的代码可以运行文件并显示我的姓名列表。现在我想使用 Pack URI 在每个名称旁边添加一个图标。所以从 this question 我可以看到最好的方法是模板化 Header
所以我首先尝试像问题
<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>
但这给了我错误:
Specified element is already the logical child of another element.
Disconnect it first.
所以我经过一些研究后尝试了:
<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>
但是现在我的名字都是ControlTemplate,没有图标显示...
如何通过 ItemContainerStyle 将图标添加到上下文菜单的菜单项?
编辑
我试过:
<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>
我得到了图标渲染,但只针对菜单中的最后一项?
问题是您不能在多个地方使用一种视觉对象。您可以使用 HeaderTemplate
代替 Header
,但使用 DataTemplate
代替 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>
请注意,此解决方案会将图标放在 MenuItem
的内容部分,而不是图标。另一种解决方案是将 MenuItem
的 Icon
属性 设置为另一个 Setter
但在这种情况下 Image
需要
将 Resource
与 x:Shared
设置为 false 分开,否则您将遇到同样的问题,即只有最后一项有图标。
<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>
所以我有一个 Context Menu
和一个 MenuItem
在里面,它分成一个名字列表:
<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>
现在上面的代码可以运行文件并显示我的姓名列表。现在我想使用 Pack URI 在每个名称旁边添加一个图标。所以从 this question 我可以看到最好的方法是模板化 Header
所以我首先尝试像问题
<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>
但这给了我错误:
Specified element is already the logical child of another element. Disconnect it first.
所以我经过一些研究后尝试了:
<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>
但是现在我的名字都是ControlTemplate,没有图标显示...
如何通过 ItemContainerStyle 将图标添加到上下文菜单的菜单项?
编辑
我试过:
<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>
我得到了图标渲染,但只针对菜单中的最后一项?
问题是您不能在多个地方使用一种视觉对象。您可以使用 HeaderTemplate
代替 Header
,但使用 DataTemplate
代替 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>
请注意,此解决方案会将图标放在 MenuItem
的内容部分,而不是图标。另一种解决方案是将 MenuItem
的 Icon
属性 设置为另一个 Setter
但在这种情况下 Image
需要
将 Resource
与 x:Shared
设置为 false 分开,否则您将遇到同样的问题,即只有最后一项有图标。
<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>