动态地将ContextMenu项目绑定到静态定义的菜单项

4
我的应用程序包含一个支持一组命令的TreeView,但是这些命令可能会在菜单之间移动,只出现在某些菜单上而不出现在其他菜单上,或者在多个菜单之间共享等。
我知道我在编译时所支持的所有命令集合,因此理论上我可以在我的部分中为每个命令定义一个具有x:Key属性的资源。然而,对于任何单击的节点,只能在运行时确定出现哪些菜单项。我可以将ContextMenu.ItemsSource绑定到返回一个MenuItem[]的应用程序中的内容,但是为了构建此数组,我需要访问在XAML文件中静态定义的MenuItems。
我做错了吗?还是有办法实现我想要的?
2个回答

6
将您的 ContextMenu.ItemsSource 绑定到 ObservableCollection,而不是 MenuItem[]。YourMenuClass 应该包含您想要绑定的标题和其他参数,例如命令。然后使用模板生成您的菜单项。
   <ContextMenu ItemsSource="{Binding MenuItemList}">
            <ContextMenu.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding Path=Name}" Command="{Binding MyCommand}" />
                </DataTemplate>
            </ContextMenu.ItemTemplate>
    </ContextMenu>

当我这样做时,菜单项看起来很奇怪。它被拉长了,左右两侧有大量的填充,并且我不知道为什么。以下是添加了2个菜单项后的示例。http://i.imgur.com/O8is6O1.png请注意,较暗的高亮矩形特别奇怪。如果我将鼠标悬停在较暗的矩形范围之外,它就会消失。就像ContextMenu本身不知道如何正确调整大小一样。 - Zachary Turner
2
由于某些原因,我不得不在<DataTemplate>中使用<TextBlock>,然后它就可以工作了。我猜否则它会将一个MenuItem放在另一个MenuItem里面?不确定它在幕后是如何工作的,但是将上面的<MenuItem>更改为<TextBlock>可以解决问题。虽然这样做,我必须把Command放在其他地方。在这种情况下,我通过在TargetType="MenuItem"的Style上使用<Setter>来使其工作。 - Zachary Turner
好的,很抱歉,但我无法解释这种行为。 - Chrille
请参考此答案来解决菜单项内部的问题。 - JonasH

2

不要使用Itemtemplate,而是为上下文菜单提供ItemContainer样式。这样,您就可以避免在上面的评论中提到的将菜单项放在另一个菜单项内的问题。

最初的回答:

提供ItemContainer样式以供上下文菜单使用,而不是使用Itemtemplate。这样一来,您就可以避免像上面评论中所提到的将菜单项放在另一个菜单项内的问题。

       `<ContextMenu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Header" Value="{Binding Name}"/>
            </Style>
        </ContextMenu.ItemContainerStyle>`

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