在ViewModel中使用内置WPF命令

时间:2011-01-27 22:26:15

标签: wpf mvvm

好的,所以我试图掌握WPF命令的概念。它们看起来非常简单,直到您尝试将命令转发给不是XAML代码的东西。我已经看到了使用自定义命令执行此操作的几种方法,但没有直接解释如何使用内置WPF命令执行此操作。像“打开”,“保存”,“剪切”等等。

是否有一种简单的方法,使用RelayCommand类或其他方法将Open命令转发到我的ViewModel?

4 个答案:

答案 0 :(得分:6)

WPF的内置ApplicationCommands之类的内容最初并未设计为MVVM,因此当您尝试将它们放入ViewModel时,它们并不真正匹配。

在WPF 4中,现在可以将InputCommands绑定到ViewModel:

https://www.thomaslevesque.com/2009/10/26/vs2010-binding-support-in-inputbindings/

另一种方法是使用DelegateCommands,您可以自行实施,也可以从Prism等库中获取。您可以将DelegateCommand定义为viewmodel中的对象,并从视图中绑定到该对象。

完成绑定后,您可以在viewmodel代码中定义命令的作用。

答案 1 :(得分:3)

如果您正在使用WPF进行MVVM,我强烈建议您查看一个框架来帮助您,例如:

  1. Prism(提供自己的DelegateCommand)
  2. MVVM Light Toolkit(提供自己的RelayCommand)
  3. Caliburn.Micro(我最喜欢的,提供动作)

答案 2 :(得分:1)

一种方法是使用附加属性来允许ViewModel在视图上定义CommandBindings。查看我的博客文章了解详细信息:

CommandBindings with MVVM

答案 3 :(得分:0)

假设您的ViewModel公开了一个New命令。您可以使用此类代码将Application.New命令绑定重新路由到VM。在XAML中:

<Window.CommandBindings>
    <CommandBinding Command="New" />
    ...
</Window.CommandBindings>

然后在代码中你可以做这样的事情。 (我喜欢将代码保留在后面的代码中,所以我把它放在实用程序类中。)

foreach (CommandBinding cb in CommandBindings)
{
    switch (((RoutedUICommand)cb.Command).Name)
    {
        case "New":
            cb.Executed += (sender, e) => ViewModel.New.Execute(e);
            cb.CanExecute += (sender, e) => e.CanExecute = ViewModel.New.CanExecute(e);
            break;
    }
}

匿名方法在RoutedUICommand和ICommand之间提供了一个thunk。

编辑:或者,最好使用CommandManager显式设置命令绑定,而不是添加处理程序。

CommandManager.RegisterClassCommandBinding(typeof(MainWindow),
    new CommandBinding(ApplicationCommands.New,
        (sender, e) => ViewModel.NewScore.Execute(e),
        (sender, e) => e.CanExecute = ViewModel.NewScore.CanExecute(e)));