C#中的RelayCommand

时间:2012-07-01 23:08:17

标签: c# silverlight mvvm delegates icommand

我正在从

学习用于C#Silverlight开发的MVVM

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

我对上下文中提到的RelayCommand类感到困惑。代码是:

public class RelayCommand : ICommand
{
#region Fields

readonly Action<object> _execute;
readonly Predicate<object> _canExecute;        

#endregion // Fields

#region Constructors

public RelayCommand(Action<object> execute)
: this(execute, null)
{
}

public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
    if (execute == null)
        throw new ArgumentNullException("execute");

    _execute = execute;
    _canExecute = canExecute;           
}
#endregion // Constructors

#region ICommand Members

[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
    return _canExecute == null ? true : _canExecute(parameter);
}

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

public void Execute(object parameter)
{
    _execute(parameter);
}

#endregion // ICommand Members
}

在这种情况下,我真的不明白_execute_canExecute的工作原理。 (我是C#的新手,甚至不确定什么是Action和Predicate。我知道他们是代表,但他们之间的区别是什么以及它们是如何工作的?)
而且,在程序中,我没有得到这条线

    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }

有人可以给我解释一下,谢谢!

2 个答案:

答案 0 :(得分:2)

RelayCommand需要两条信息:

  1. 执行命令时应运行的代码(_execute操作)
  2. 应运行哪些代码来确定是否可以执行此命令(_canExecute谓词)
  3. Action是一个委托,代表返回void的方法。在这种情况下,_execute操作需要一个参数(object)并返回void

    Predicate是一个委托,它接受一个值并返回一个布尔结果。在这种情况下,_canExecute谓词采用object值并返回bool

    _execute_canExecute值在构造时都会提供给RelayCommand,因为这些值是命令中每个命令唯一的部分。

    关于CanExecuteChanged事件:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    

    当订阅者订阅该活动时,会调用add,当他们取消订阅时,会调用remove。上述CanExecuteChanged事件只是一个传递事件(即如果订阅者订阅了CanExecuteChanged事件,他们会自动订阅CommandManager.RequerySuggested事件。根据{{​​3}},CommandManager.RequerySuggested事件......

      当CommandManager检测到可能改变命令执行能力的条件时,会发生

    我相信订阅者很可能在触发此事件时调用CanExecute上的RelayCommand方法来确定命令是否仍然可以执行。

答案 1 :(得分:1)

添加/删除类似于属性获取/设置,而是用于事件。

时会调用添加代码
RelayCommandInstance.CanExecuteChanged += MyChangedEventHandler 

已执行。执行 - =时调用删除代码。您不会非常看到此语法,因为您很少需要覆盖在事件调用列表中添加/删除委托的默认行为。

在这种情况下,RelayCommand只是将其CanExecuteChanged事件映射到CommandManager.RequerySuggested事件。