使用ItemContainerStyle时如何在ContextMenu的MenuItem中设置Icon

时间:2015-03-17 11:24:00

标签: wpf contextmenu menuitem controltemplate

所以我有一个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>

现在上面的代码工作文件并显示我的名字列表。现在我想使用包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>

但这给了我错误:

  

指定的元素已经是另一个元素的逻辑子元素。   首先断开它。

所以我经过一些研究后尝试过:

<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>

我得到一个图标渲染,但仅限于菜单中的最后一项?

1 个答案:

答案 0 :(得分:9)

问题是你不能在一个地方使用一个视觉。您可以使用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的内容部分放置图标,而不是图标。另一种解决方案是将Icon的{​​{1}}属性设置为另一个MenuItem,但在这种情况下Setter需要 单独Image并将Resource设置为false,否则您最终会遇到同一问题,其中只有最后一项有图标。

x:Shared