在menuitem中输入WPF ContextMenu itemtemplate,menuitem

时间:2015-03-18 19:01:01

标签: c# wpf contextmenu menuitem

我有以下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的列表。

数据绑定到contextmenu,但它在UI中反映为MenuItem中的MenuItem(具有额外的边距,使菜单非常大)。我可以通过将DataTemplate中的MenuItem更改为TextBox来解决这个问题,但之后我再也无法绑定IsSelected(我需要可视化属性)。

我对此有几个问题:

  • 为什么MenuItem中有MenuItem?这对我来说没有意义,因为它没有绑定到菜单项列表而是绑定到TestItemModel列表。
  • 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:17)

因为MenuItem是容器类型,当它将您的视图模型转换为可视项时,它会将您的模板包装在MenuItem中。以ListBox创建ListBoxItemListView将使用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.HeaderIsChecked属性仍然需要绑定在ItemContainerStyle