为什么使用 RelayCommand [英] Why RelayCommand

查看:31
本文介绍了为什么使用 RelayCommand的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在 WPF 中进行了大量编程,但此时我的 View 和 ViewModel 并不是分开的.嗯,它是部分.我所有与文本框中的文本、标签内容、数据网格中的列表有关的绑定都是由常规属性完成的,其中包含 NotifyPropertyChanged 事件.

I've been programming a lot in WPF lately but my View and ViewModel are not separate at this point. Well, it's partially. All my bindings concerned to text in text boxes, content for labels, lists in datagrids, ... are done by regular properties with a NotifyPropertyChanged event in them.

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

All my events for handling button clicks or text changed stuff is done by linking the events. Now, I wanted to start working with commands and found this article: http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute. It has an explanation of how to set up MVVM but I'm confused with the RelayCommand.

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

What job does it do? Is it useable for all commands in my form? How do I make the button disable when (a) certain text box(es) are not filled in?

编辑 1:

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

A good explanation to "Is it useable for all commands in my form?" is answered here: https://stackoverflow.com/a/22286816/3357699

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

Here is the code I have so far: https://stackoverflow.com/a/22289358/3357699

推荐答案

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

Commands are used to separate the semantics and the object that invokes a command from the logic that executes the command i.e. it separates UI component from the logic that needs to be executed on command invocation. So, that you can test business logic separately using test cases and also your UI code is loosely coupled to business logic.

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

Now, that being said let's pick your questions one by one:

它做什么工作?

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

I have added the details above. Hope it clears the usage of commands.

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

Is it usable for all commands in my form?

一些控件公开了命令依赖属性,如按钮、菜单项等,它们注册了一些默认事件.对于 Button,它是 Click 事件.因此,如果您将 ViewModel 中声明的 ICommand 与 Button 的 Command DP 绑定,则只要单击按钮,就会调用它.

Some controls exposed Command DependencyProperty like Button, MenuItem etc. which have some default event registered to it. For Button it's Click event. So, if you bind ICommand declared in ViewModel with Button's Command DP, it will be invoked whenever button is clicked on.

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

For other events, you can bind using Interactivity triggers. Refer to the sample here how to use them to bind to ICommand in ViewModel.

当 (a) 某些文本框未显示时,如何禁用按钮填写了吗?

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

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

The link you posted doesn't provide complete implementation of RelayCommand. It lacks the overloaded constructor to set CanExecute predicate which plays a key role in enabling/disabling the UI control to which your command is bind to.

将 TextBox 与 ViewModel 和 CanExecute 中的某些属性绑定,如果任何绑定属性为 null 或为空,则委托返回 false,这会自动禁用绑定命令的控件.

Bind TextBoxes with some properties in ViewModel and in CanExecute delegate returns false if any of the binded property is null or empty which automatically disabled the control to which command is binded to.

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
}

这篇关于为什么使用 RelayCommand的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆