通过绑定部分填充菜单项

3

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


好问题!我的第一反应是将两个菜单无缝合并,以便提供单个菜单的视觉体验,并在Xaml中完成整个过程。像你一样,如果有任何绕过代码的方法,我都会避免使用代码,在这种情况下确实有。我会关注这里的答案! - Gayot Fow
将MenuItems绑定到ObservableCollection<CustomObject>是否适合您?您可以通过在linq查询中使用OrderBy方法进行排序,将您所说的静态对象放在列表底部。不确定这是否是您要寻找的... - user1795804
还是你只是在谈论如何合并和排序这两个集合? - user1795804
@Killingsworth,这就是我在谈论通过编程生成第二个集合时所指的内容,并且这也正是我希望避免采用的方法。 - Abion47
2个回答

5

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

简单、简洁、直接。我喜欢它。 - Abion47
1
从来没有人指责过我不够简洁,+1 - McGarnagle

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所述。因此,您将不再使用<CollectionContainer Collection="{Binding MyMenuItems}" />,而是使用:
<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}"/>

1
值得注意的是,代理代码的唯一原因是由于ContextMenu,它不是可视树的一部分。标准菜单控件不会有这个问题。 - 17 of 26

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