WPF ContextMenu itemtemplate,menuitem里面的menuitem
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29130567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ContextMenu itemtemplate, menuitem inside menuitem
提问by The Cookies Dog
I have the following xaml:
我有以下 xaml:
<ContextMenu ItemsSource="{Binding TestItems}">
<ContextMenu.ItemTemplate>
<DataTemplate DataType="models:TestItemModel">
<MenuItem IsChecked="{Binding IsSelected}" Header="{Binding Header}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
The TestItemModel class only consists of a IsSelected boolean property and a Header string property.
TestItemModel 类仅包含一个 IsSelected 布尔属性和一个 Header 字符串属性。
TestItems is a list of TestItemModels.
TestItems 是 TestItemModels 的列表。
The data is binded to the contextmenu but it is reflected in the UI as a MenuItem inside a MenuItem (with the additional margins as such, making the menu very big). I can fix this by changing the MenuItem inside the DataTemplate to a TextBox, but then I cannot bind the IsSelected anymore (which I need for visualization properties).
数据绑定到上下文菜单,但它在 UI 中反映为 MenuItem 内的 MenuItem(具有额外的边距,使菜单变得非常大)。我可以通过将 DataTemplate 内的 MenuItem 更改为 TextBox 来解决此问题,但随后我无法再绑定 IsSelected(我需要可视化属性)。
There are a couple of questions I have regarding this:
关于这个,我有几个问题:
- Why is there a MenuItem inside a MenuItem? This doesn't make sense to me as it's not binded to a menuitem list but to a list of TestItemModels.
- How can I resolve this?
- 为什么 MenuItem 里面有一个 MenuItem?这对我来说没有意义,因为它没有绑定到菜单项列表,而是绑定到 TestItemModels 列表。
- 我该如何解决这个问题?
回答by dkozl
Because MenuItemis the container type and when it translates your view model into visual item it will wrap your template in MenuItem. In the same way ListBoxwill create ListBoxItemor ListViewwill use ListViewItem. To bind properties of the wrapper you need to use ItemContainerStyle
因为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>
or, if you prefer, you can do it partially with ItemTemplateand ItemContainerStyle
或者,如果您愿意,您可以部分使用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>
In this scenario whatever is in ItemTemplatewill become MenuItem.Headerbut IsCheckedproperty still needs to be bound in ItemContainerStyle
在这种情况下,任何内容都ItemTemplate将成为MenuItem.Header但IsChecked仍然需要绑定属性ItemContainerStyle

