【问题标题】:ContextMenu in MVVMMVVM 中的上下文菜单
【发布时间】:2013-03-12 02:26:50
【问题描述】:

我想将上下文菜单绑定到命令列表。

<Grid.ContextMenu>
    <ContextMenu ItemsSource="{Binding ItemContextCommands, Converter={StaticResource commandToStringConverter}}">
            <ContextMenu.ItemTemplate >
                    <DataTemplate DataType="MenuItem">
                            <MenuItem Command="{Binding}"></MenuItem>
                        </DataTemplate>
                </ContextMenu.ItemTemplate>
        </ContextMenu>
</Grid.ContextMenu>

commandToStringConverter 只是将命令列表转换为字符串列表,在列表中的每个命令上调用 ToString()

如何实现每个MenuItem 中的Command 被调用?

【问题讨论】:

  • 可能应该考虑使用另一个转换器,将每个 {Binding} 转换为实际的命令调用。
  • 转换器返回一个函数列表?

标签: c# wpf mvvm binding contextmenu


【解决方案1】:

我会使用一个小的“视图模型”来保存此类命令的信息。

class ContextAction : INotifyPropertyChanged
{
    public string Name;
    public ICommand Action;
    public Brush Icon;
}

在您的视图模型中创建一个集合,该集合应该获得诸如

之类的上下文操作
ObservableCollection<ContextAction> Actions {get;set;}

只需将此集合绑定到您的ContextMenu

<Grid.ContextMenu>
    <ContextMenu ItemsSource="{Binding Actions}" />

上下文菜单项的ItemTemplate 现在可以访问名称、命令以及您可能需要的任何其他内容。更改CommandParameter 也可能很有用,这样它就会使用动作拥有元素而不是动作本身来调用命令。

【讨论】:

  • 有人知道如何处理带有分隔符和子菜单的 ContextMenu 吗?这个解决方案似乎只对一组同类对象有用。
  • 子菜单同样简单。您只需为 ContextMenu 提供一个带有 ItemsSource 设置器的 ItemContainerStyle,并绑定到 ContextAction 内的 ObservableCollection 类型的新属性。对于分隔符,请参阅this 解决方案。
【解决方案2】:

我使用这样的东西:

public class ContextMenuVM
{ 
    public string Displayname {get;set;}
    public ICommand MyContextMenuCommand {get;set;}
}

在您的上下文菜单数据上下文中:

public ObservableCollection<ContextMenuVM> MyCommandList {get;set;}

在您的 xaml 中

<ContextMenu ItemsSource="{Binding MyCommandList}">
        <ContextMenu.ItemTemplate >
                <DataTemplate DataType="MenuItem">
                        <MenuItem Header="{Binding Displayname}" Command="{Binding MyContextMenuCommand}"></MenuItem>
                    </DataTemplate>
            </ContextMenu.ItemTemplate>
    </ContextMenu>

它是在没有 ide 的情况下编写的,所以可能存在一些语法错误

【讨论】:

  • 此解决方案嵌套了 MenuItem 控件
【解决方案3】:

@blindmils 解决方案的改进 XAML 版本如下:

<ContextMenu ItemsSource="{Binding MyCommandList}">
    <ContextMenu.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding Displayname}" />
            <Setter Property="Command" Value="{Binding MyContextMenuCommand }" />
        </Style>
    </ContextMenu.ItemContainerStyle>
</ContextMenu>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 2017-09-21
    • 2015-06-04
    • 2019-06-22
    • 2020-05-08
    • 1970-01-01
    相关资源
    最近更新 更多