在menuitem中输入WPF ContextMenu itemtemplate,menuitem

The*_*Dog 7 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>
Run Code Online (Sandbox Code Playgroud)

TestItemModel类仅包含IsSelected布尔属性和Header字符串属性.

TestItems是TestItemModels的列表.

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

我对此有几个问题:

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

dko*_*ozl 21

因为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>
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意,可以使用ItemTemplate和部分地完成ItemContainerStyle

<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>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,任何内容都ItemTemplate将成为MenuItem.HeaderIsChecked属性仍然需要被绑定ItemContainerStyle

  • 没问题@Areius。很高兴它有所帮助。 (2认同)