wpf MVVM 中的上下文菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15566824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:14:45  来源:igfitidea点击:

ContextMenu in MVVM

c#wpfmvvmbindingcontextmenu

提问by Mare Infinitus

I want to bind a contextmenu to a list of commands.

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

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

The commandToStringConvertersimply converts a list of commands to a list of strings calling the ToString()on each command in the list.

commandToStringConverter简单的命令列表转换为字符串调用列表ToString()列表中的每个命令。

How can I achieve that the Commandin each MenuItemis called?

我怎样才能实现Command在每个MenuItem被调用?

回答by dowhilefor

I would use a small "view model" to hold the informations for such a command.

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

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

make a collection inside your view model which should get the context actions like

在您的视图模型中创建一个集合,它应该获得上下文操作,例如

ObservableCollection<ContextAction> Actions {get;set;}

and simply bind this collection to your ContextMenu.

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

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

The ItemTemplatefor the contextmenu items can now access the name, the command and whatever else you might need. It might be useful to change the CommandParameteras well so that it will call the command with the actions owning element, not with the action itself.

ItemTemplate对文本菜单项目现在可以访问的名称,命令和其他任何你可能需要。更改 也可能很有用,CommandParameter以便它将使用操作拥有元素而不是操作本身调用命令。

回答by blindmeis

i use something like this:

我使用这样的东西:

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

in your contextmenu datacontext:

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

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

in your xaml

在你的 xaml

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

its written without ide, so maybe some syntax errors in there

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

回答by Ole K

An improved XAML version of @blindmils solution below:

下面是@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>