绑定WPF菜单到ItemsSource时出现问题

3
我希望避免在XAML或代码中手动构建菜单,而是通过绑定到一个ICommand派生对象列表来实现。但是,我遇到了一个问题,即生成的菜单有两个级别的菜单项(即每个MenuItem包含在一个MenuItem中):

alt text

我的猜测是这种情况发生的原因是WPF自动为我的绑定生成了一个MenuItem,但我正在使用的“viewer”实际上已经是一个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>
来自http://bea.stollnitz.com/blog/?p=23,它允许我在绑定源中使用元素。

因此,菜单绑定到一组,每个项的CommandParameter设置为相同的全局目标(这恰好是一个集合,但这并不重要)。

我的问题是,有没有办法使WPF不自动将每个项包装在中?

2个回答

3

很遗憾,我发现解决这个问题的最佳方法是使用菜单项的样式而不是项模板。然后,样式中的每个属性都可以绑定到您对象上的属性。例如:

<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,这是更好的方法,但这是我找到的唯一能正常工作的方式。


这其实就是我的NoteCommandMenuItemViewer类正在做的事情,所以我想这样做并不会有太大损失。 - devios1

2

我倾向于子类化ContextMenu并重写GetContainerForItemOverride:

public class ContextMenuWithNoteCommands : ContextMenu
{
  protected virtual DependencyObject GetContainerForItemOverride()
  {
    return new NoteCommandMenuItemViewer();
  }
}

然后在NoteCommandMenuItemViewer样式中设置CommandParameter绑定,或者在ContextMenu.ItemContainerStyle中设置,以适合您的需求。

这假定您不能简单地使用常规MenuItem上的ItemContainerStyle来获得所需的效果:

<ContextMenu ...>
  <ContextMenu.ItemContainerStyle>
    <Style>
      ...
    </Style>
  </ContextMenu.ItemContainerStyle>
</ContextMenu>

谢谢,这是一个简单得多的解决方案! - devios1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接