WPF上下文菜单项模板,菜单项内部的菜单项

13

我有以下的XAML代码:

<ContextMenu ItemsSource="{Binding TestItems}">
     <ContextMenu.ItemTemplate>
          <DataTemplate DataType="models:TestItemModel">
              <MenuItem IsChecked="{Binding IsSelected}" Header="{Binding Header}"  />
          </DataTemplate>
     </ContextMenu.ItemTemplate>
</ContextMenu>

TestItemModel类只包含一个IsSelected布尔属性和一个Header字符串属性。

TestItems是一个TestItemModels列表。

数据绑定到上下文菜单,但在UI中反映为一个MenuItem内部的MenuItem(具有额外的边距,使菜单非常大)。我可以通过将DataTemplate内部的MenuItem更改为TextBox来解决这个问题,但这样就无法再绑定IsSelected了(我需要用于可视化属性)。

我有几个关于此事的问题:

  • 为什么会有一个MenuItem内部有另一个MenuItem?对我来说这没有意义,因为它不是绑定到菜单项列表而是绑定到TestItemModels列表。
  • 我该如何解决这个问题?
1个回答

35

因为MenuItem是容器类型,当它将您的视图模型转换为可视项时,它会将您的模板包装在MenuItem中。同样,ListBox将创建ListBoxItem,或者ListView将使用ListViewItem。要绑定包装器的属性,需要使用ItemContainerStyle

<ContextMenu ItemsSource="{Binding TestItems}">
   <ContextMenu.ItemContainerStyle>
      <Style TargetType="{x:Type MenuItem}">
         <Setter Property="IsChecked" Value="{Binding IsSelected}"/>
         <Setter Property="Header" Value="{Binding Header}"/>
      </Style>
   </ContextMenu.ItemContainerStyle>
</ContextMenu>

或者,如果您喜欢,您可以部分使用ItemTemplateItemContainerStyle来完成它。

<ContextMenu ItemsSource="{Binding TestItems}">
   <ContextMenu.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Header}"/>
      </DataTemplate>
   </ContextMenu.ItemTemplate>
   <ContextMenu.ItemContainerStyle>
      <Style TargetType="{x:Type MenuItem}">
         <Setter Property="IsChecked" Value="{Binding IsSelected}"/>
      </Style>
   </ContextMenu.ItemContainerStyle>
</ContextMenu>
在这种情况下,无论 ItemTemplate 中有什么内容都将成为 MenuItem.Header,但是 IsChecked 属性仍需要在 ItemContainerStyle 中绑定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接