无法将WPF菜单绑定到ItemsSource

时间:2010-06-11 16:48:53

标签: c# wpf binding menuitem itemssource

我希望通过绑定到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中吗?

2 个答案:

答案 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>