为什么使用RelayCommand

我最近在WPF中进行了很多编程,但是我的View和ViewModel在这个时候并不是独立的。 那是部分的 我所有与文本框中的文本,标签内容,datagrid中的列表有关的绑定,都是通过常规属性来完成的,其中包含一个NotifyPropertyChanged事件。

我所有的事件处理button点击或文本更改的东西是通过链接事件。 现在,我想开始使用命令,并find这篇文章: http : //www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute 。 它有一个如何设置MVVM的解释,但我与RelayCommand混淆。

它做什么工作? 在我的表单中的所有命令是否可用? (a)某些文本框未填写时,如何禁用button?


编辑1:

一个很好的解释是“所有的命令都适用于我的forms吗?” 在这里回答: https : //stackoverflow.com/a/22286816/3357699

这是我到目前为止的代码: https : //stackoverflow.com/a/22289358/3357699

命令用于将语义和调用命令的对象从执​​行命令的逻辑中分离出来,即将UI组件从需要在命令调用中执行的逻辑中分离出来。 因此,您可以使用testing用例分别testing业务逻辑,而且您的UI代码与业务逻辑松散耦合。

那么现在呢,让我们一一挑选你的问题:

它做什么工作?

我已经添加了上面的细节。 希望它清除命令的用法。


它是否可用于我的表单中的所有命令?

一些控件暴露了Command,DependencyProperty,像Button,MenuItem等,它们有一些默认的事件被注册到它。 对于Button,它是Click事件。 所以,如果你绑定ICommand在ViewModel中用Button的Command DP声明的话,只要点击button就会调用它。

对于其他事件,您可以使用Interactivity triggers进行绑定。 请参考这里的示例如何使用它们绑定到ViewModel中的ICommand


(a)某些文本框未填写时,如何禁用button?

您发布的链接不提供完整的RelayCommand实现。 它缺less重载的构造函数来设置CanExecute谓词,它在启用/禁用您的命令绑定到的UI控件中起着关键作用。

使用ViewModel中的某些属性绑定CanExecute如果任何绑定属性为null或空, CanExecute委托会返回false,这会自动禁用命令绑定到的控件。


全面实施RelayCommand

 public class RelayCommand<T> : ICommand { #region Fields readonly Action<T> _execute = null; readonly Predicate<T> _canExecute = null; #endregion #region Constructors /// <summary> /// Initializes a new instance of <see cref="DelegateCommand{T}"/>. /// </summary> /// <param name="execute">Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate.</param> /// <remarks><seealso cref="CanExecute"/> will always return true.</remarks> public RelayCommand(Action<T> execute) : this(execute, null) { } /// <summary> /// Creates a new command. /// </summary> /// <param name="execute">The execution logic.</param> /// <param name="canExecute">The execution status logic.</param> public RelayCommand(Action<T> execute, Predicate<T> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion #region ICommand Members ///<summary> ///Defines the method that determines whether the command can execute in its current state. ///</summary> ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> ///<returns> ///true if this command can be executed; otherwise, false. ///</returns> public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute((T)parameter); } ///<summary> ///Occurs when changes occur that affect whether or not the command should execute. ///</summary> public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } ///<summary> ///Defines the method to be called when the command is invoked. ///</summary> ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param> public void Execute(object parameter) { _execute((T)parameter); } #endregion } 

使用relay命令的好处是可以直接将命令绑定到ViewModels。 通过以这种方式使用命令,可以避免在视图代码隐藏中编写代码。

使用继电器命令时,必须提供两种方法。 第一个提供一个值是否命令可以执行(例如“CanExecuteSave”),而另一个将负责执行命令(“ExecuteSave”)。