通过绑定部分填充 MenuItem

Posted

技术标签:

【中文标题】通过绑定部分填充 MenuItem【英文标题】:Partially filling a MenuItem through binding 【发布时间】:2013-07-10 02:11:26 【问题描述】:

我想使用自定义对象列表来生成菜单中的 MenuItems 列表,但在该菜单的底部,我希望始终出现几个静态 MenuItems。从逻辑上讲,在我的脑海中,这可以通过以编程方式创建另一个列表来绑定,该列表总是在底部有那些 MenuItems,但这让我觉得这是一种天真的方法。我确信有一种更优雅的方法可以使用我已经拥有的列表以及一些 XAML 魔法,可能使用某种 DataTemplate。有什么指点吗?

【问题讨论】:

好问题!我的直接预感是无缝地合并这两者,以便提供单个菜单的视觉体验,并在 Xaml 中完成所有工作。我和你一样,如果有任何方法可以避免代码,在这种情况下是有的。我会感兴趣地看这里的答案! 将 MenuItems 绑定到 ObservableCollection 对您有用吗?您可以通过在 linq 查询中使用 OrderBy 方法进行排序,将您所说的静态对象放在列表底部。不确定这是否是您要找的... 或者你只是在谈论合并和排序两个集合? @Killingsworth 这就是我在谈到以编程方式生成第二个集合时所指的,也是我希望避免的那种方法。 【参考方案1】:

就像 McGarnagle 所说,您可以使用 CompositeCollection。但是,您不需要为固定菜单项创建资源。您可以像这样将它们直接放在 CompositeCollection 中:

<Menu>
    <Menu.ItemsSource>
        <CompositeCollection>
            <CollectionContainer Collection="Binding Path=MyItems" />
            <Separator/>
            <MenuItem Header="Fixed item 1" />
            <MenuItem Header="Fixed item 2" />
        </CompositeCollection>
    </Menu.ItemsSource>
</Menu>

【讨论】:

简单、简洁、直接。我喜欢它。 从来没有人指责我言简意赅,+1【参考方案2】:

使用CompositeCollection,带有两个子集合(生成的菜单项和静态的)。

编辑应该如下所示:

<Button Content="Test">
    <Button.Resources>
        <viewModel:MenuItemCollection x:Key="FixedMenuItems">
            <MenuItem Header="Fixed Item" />
        </viewModel:MenuItemCollection>
    </Button.Resources>

    <Button.ContextMenu>
        <ContextMenu>
            <ContextMenu.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer Collection="StaticResource FixedMenuItems" />
                    <CollectionContainer Collection="Binding MyMenuItems" />
                </CompositeCollection>
            </ContextMenu.ItemsSource>
        </ContextMenu>
    </Button.ContextMenu>

</Button>

其中viewModel:MenuItemCollection 只是MenuItem 的列表:

public class MenuItemCollection : ObservableCollection<MenuItem>


二次编辑

为此需要一个修复程序。要绑定到视图模型中的“MyMenuItems”,必须使用this answer 中所述的代理。所以你最终会使用:

而不是&lt;CollectionContainer Collection="Binding MyMenuItems" /&gt;
<CollectionContainer Collection="Binding Path=DataContext.MyMenuItems,Source=StaticResource ProxyElement" />

并将代理添加到视图顶部:

<UserControl.Resources>
    <FrameworkElement x:Key="ProxyElement" DataContext="Binding"/>
<UserControl.Resources>
<ContentControl Visibility="Collapsed" Content="StaticResource ProxyElement"/>

【讨论】:

值得注意的是,代理代码的唯一原因是因为 ContextMenu,它不是可视化树的一部分。标准的 Menu 控件不会有这个问题。

以上是关于通过绑定部分填充 MenuItem的主要内容,如果未能解决你的问题,请参考以下文章

DataGridView(部分)数据绑定自定义排序

绑定组合框在(重新)填充数据源时更改 SelectedItem

如何基于二维数组填充 WPF 网格

在控制器内的http调用之后加载部分文件

使用 DataBinding 的 ListBox 填充速度极慢

通过部分填充从 Oracle 过程返回对象类型?