实现自定义WPF命令

我想实现一个自定义WPF命令,我搜索并找到以下代码:

public static class CustomCommands { public static readonly RoutedUICommand Exit = new RoutedUICommand ( "Exit", "Exit", typeof(CustomCommands), new InputGestureCollection() { new KeyGesture(Key.F4, ModifierKeys.Alt) } ); //Define more commands here, just like the one above } 

有两件事我无法弄清楚。

  1. 是否需要static readonly命令? 不能我们只使用const声明它吗?

  2. 究竟什么是new InputGestureCollection() { new KeyGesture(Key.F4, ModifierKeys.Alt) } ? 如果它调用默认构造函数并初始化属性,那么应该有一个属性要分配,但没有任何内容可以分配。 InputGestureCollection有大括号,但在大括号内它没有初始化任何属性。 怎么样? 这种陈述是什么?

不,这不是一个好方法。

首先,您需要通过MVVM对WPF有一些基本的了解。 您有一个要绑定到UI的类。 那个类不是.xaml.cs

它完全独立于View。 您需要将类的实例放入Window的DataContext中,您可以在.xaml.cs中通过调用sth来执行此操作:

 this.DataContext = new MyViewModel(); 

现在你的类MyViewModel需要一个ICommand类型的属性。 最佳实践是创建一个实现ICommand的类。 通常你称之为DelegateCommand或RelayCommand。 例:

 public class DelegateCommand : ICommand { private readonly Predicate _canExecute; private readonly Action _execute; public event EventHandler CanExecuteChanged; public DelegateCommand(Action execute) : this(execute, null) { } public DelegateCommand(Action execute, Predicate canExecute) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { if (_canExecute == null) { return true; } return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) { CanExecuteChanged(this, EventArgs.Empty); } } } 

然后在ViewModel中创建一个属性,其中包含该类的实例。 像那样:

 public class MyViewModel{ public DelegateCommand AddFolderCommand { get; set; } public MyViewModel(ExplorerViewModel explorer) { AddFolderCommand = new DelegateCommand(ExecuteAddFolderCommand, (x) => true); } public void ExecuteAddFolderCommand(object param) { MessageBox.Show("this will be executed on button click later"); } } 

在您的视图中,您现在可以将按钮的命令绑定到该属性。

  

路由命令是默认情况下框架中已存在的内容(复制,粘贴等)。 如果您是MVVM的初学者,在获得对“普通”命令的基本理解之前,不应该考虑创建路由命令。

回答你的第一个问题:使Commands为static和/或const绝对没有必要。 (参见MyViewModel类)

第二个问题:您可以使用放入{ -brackets的默认值初始化列表。 例:

 var Foo = new List(){ "Asdf", "Asdf2"}; 

您没有初始化属性的对象。 您有一个初始化的列表,然后使用您放在{ -brackets中的参数调用Add()

这也是你的情况基本发生的事情。 您有一个使用某些值初始化的集合。

回答你的第二个问题:

 new InputGestureCollection() { new KeyGesture(Key.F4, ModifierKeys.Alt) } 

这是集合初始值设定项的示例,相当于:

 var collection = new InputGestureCollection(); collection.Add(new KeyGesture(Key.F4, ModifierKeys.Alt)); 

这只是一个简写,ReSharper建议的东西。