我希望通过绑定到ICommand
派生对象的列表,避免在XAML或代码中手动构建菜单。但是,我遇到了一个问题,结果菜单有两级菜单项(即每个MenuItem
都包含在MenuItem
中):
alt text http://i47.tinypic.com/j63lg2.png
我的猜测是这种情况正在发生,因为WPF会自动为我的绑定生成MenuItem
,但我正在使用的“查看器” 是MenuItem
(它来自MenuItem
):
<ContextMenu
x:Name="selectionContextMenu"
ItemsSource="{Binding Source={x:Static OrangeNote:Note.MultiCommands}}"
ItemContainerStyleSelector="{StaticResource separatorStyleSelector}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<Viewers:NoteCommandMenuItemViewer
CommandParameter="{Binding Source={x:Static OrangeNote:App.Screen}, Path=SelectedNotes}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
(ItemContainerStyleSelector来自http://bea.stollnitz.com/blog/?p=23,它允许我在我的绑定源中包含Separator
元素。)
因此,菜单绑定到ICommand
s的集合,并且每个项目的CommandParameter
都设置为相同的全局目标(恰好是一个集合,但这并不重要)。< / p>
我的问题是,有什么方法可以绑定它,以便WPF不会自动将每个项目包装在MenuItem
中吗?
答案 0 :(得分:3)
不幸的是,我发现解决这个问题的最好方法是使用MenuItems的样式,而不是ItemTemplate。然后,样式中的每个属性都可以绑定到对象的属性。像这样的东西,例如:
<Style x:Key="SelectionContextMenuStyle" TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Path=Text}" />
<Setter Property="Command" Value="{Binding Path=Command}" />
<Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
</Style>
看起来真的像ItemTemplate应该有效,这将是更好的方法,但这是我发现实际上正常工作的唯一方法。
答案 1 :(得分:2)
我倾向于继承ContextMenu并覆盖GetContainerForItemOverride:
public class ContextMenuWithNoteCommands : ContextMenu
{
protected virtual DependencyObject GetContainerForItemOverride()
{
return new NoteCommandMenuItemViewer();
}
}
然后在NoteCommandMenuItemViewer样式中或在ContextMenu.ItemContainerStyle中设置CommandParameter绑定,以更合适的为准。
这假设你不能简单地在常规MenuItem上使用ItemContainerStyle来获得你想要的效果:
<ContextMenu ...>
<ContextMenu.ItemContainerStyle>
<Style>
...
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>