c# - 为什么选择 RelayCommand

标签 c# wpf mvvm binding relaycommand

我最近在 WPF 中进行了大量编程,但此时我的 View 和 ViewModel 并没有分开。好吧,这是部分的。我所有与文本框中的文本、标签内容、数据网格中的列表等相关的绑定(bind)都是由带有 NotifyPropertyChanged 事件的常规属性完成的。

我所有处理按钮点击或文本更改的事件都是通过链接事件来完成的。现在,我想开始使用命令并找到这篇文章:http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute .它解释了如何设置 MVVM,但我对 RelayCommand 感到困惑。

它做什么工作? 它可用于我表单中的所有命令吗? 当 (a) 某些文本框未填写时,如何使按钮禁用?


编辑 1:

对“它对我表单中的所有命令都可用吗?”的一个很好的解释在这里回答:https://stackoverflow.com/a/22286816/3357699

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

最佳答案

命令用于将调用命令的语义和对象与执行命令的逻辑分开,即将 UI 组件与需要在命令调用时执行的逻辑分开。因此,您可以使用测试用例单独测试业务逻辑,而且您的 UI 代码与业务逻辑松耦合。

现在,话虽如此,让我们一一挑选您的问题:

What job does it do?

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


Is it usable for all commands in my form?

一些控件公开了 Command DependencyProperty,例如 Button、MenuItem 等,其中注册了一些默认事件。对于 Button,它是 Click 事件。因此,如果您将在 ViewModel 中声明的 ICommand 与 Button 的 Command DP 绑定(bind),则只要单击按钮,就会调用它。

对于其他事件,您可以使用交互触发器 进行绑定(bind)。引用样本here如何使用它们绑定(bind)到 ViewModel 中的 ICommand


How do I make the button disable when (a) certain text box(es) are not filled in?

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

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


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 || _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
}

关于c# - 为什么选择 RelayCommand,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22285866/

相关文章:

c# - 检测弹出窗口何时/是否决定重新定位自身

c# - c#中连字符的不间断字符是什么?

c# - 复选框显示/隐藏文本框 WPF

c# - 根据多个TextBoxes MVVM中的值过滤WPF DataGrid(数据表)

c# - SqlCommand 是否优化了参数化的sql 语句?

c# - Twitter API : 401 on POST, GET 工作正常

c# - 使用 'Microsoft.Office.Interop.Word._Document.Close' 时出现警告 CS0467

c# - 以编程方式生成 Resource Designer cs

wpf - 在鼠标悬停或焦点上应用条件样式

wpf - DataGrid 选定项绑定(bind)