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

发布于 2024-09-05 03:22:39 字数 1377 浏览 7 评论 0原文

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

替代文字< /a>

我的猜测是,发生这种情况是因为 WPF 会自动为我的绑定生成一个 MenuItem,但我使用的“查看器”实际上已经一个 MenuItem< /code> (它源自 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 集合,并且每个项目的 CommandParameter 设置为相同的全局目标(恰好是一个集合,但这并不重要) 。

我的问题是,有什么方法可以绑定它,以便 WPF 不会自动将每个项目包装在 MenuItem 中?

I would like to avoid having to build a menu manually in XAML or code, by binding to a list of ICommand-derived objects. However, I'm experiencing a bit of a problem where the resulting menu has two levels of menu-items (i.e. each MenuItem is contained in a MenuItem):

alt text

My guess is that this is happening because WPF is automatically generating a MenuItem for my binding, but the "viewer" I'm using actually already is a MenuItem (it's derived from 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>

(The ItemContainerStyleSelector is from http://bea.stollnitz.com/blog/?p=23, which allows me to have Separator elements inside my bound source.)

So, the menu is bound to a collection of ICommands, and each item's CommandParameter is set to the same global target (which happens to be a collection, but that's not important).

My question is, is there any way I can bind this such that WPF doesn't automatically wrap each item in a MenuItem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

音栖息无 2024-09-12 03:22:39

不幸的是,我发现解决此问题的最佳方法是使用 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 确实应该可以工作,并且这将是更好的方法,但这是我发现实际上可以正常工作的唯一方法。

Unfortunately, the best way I've found to work around this issue is to use a style for the MenuItems, rather than an ItemTemplate. Then each property in the style can be bound to properties on your object. Something like this, for example:

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

It really seems like an ItemTemplate should work, and it would be the better way to go, but this is the only way I've found that actually works properly.

风铃鹿 2024-09-12 03:22:39

我倾向于子类化 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>

I would be inclined to subclass ContextMenu and override GetContainerForItemOverride:

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

Then set the CommandParameter binding in the NoteCommandMenuItemViewer style, or in ContextMenu.ItemContainerStyle, whichever is more appropriate.

This presumes you can't simply use ItemContainerStyle on a regular MenuItem to get the effect you want:

<ContextMenu ...>
  <ContextMenu.ItemContainerStyle>
    <Style>
      ...
    </Style>
  </ContextMenu.ItemContainerStyle>
</ContextMenu>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文