【问题标题】:Performance penalty of continuous CanExecute calls in CommandCommand 中连续 CanExecute 调用的性能损失
【发布时间】:2010-12-01 15:11:42
【问题描述】:

我正在将 MVVM 模式应用于一个项目。我有一个 UserControl,它有一个按钮,该按钮绑定到 ViewModel 公开的命令。 由于按钮是可见的,它不断地调用按钮的 CanExecute 方法。有些东西告诉我,这会带来性能损失,但我不确定。这是预期的行为吗?还是有更好的方法将按钮绑定到命令?

谢谢。

【问题讨论】:

  • 为什么按钮一直在调用CanExecute?默认情况下它不会这样做,只有在 ICommand.CanExecuteChanged 被提出时才应该这样做。
  • 您使用的是什么类型的 ICommand?在 CanExecute 更新方面,不同的实现可能会有很大的不同。
  • 我只是使用常规的 ICommand 接口。实际上是 RelayCommand 类,除了它使用委托注入来指定我的方法之外,并没有什么特别之处。

标签: wpf performance command canexecute


【解决方案1】:

抱歉,我发现了发生了什么。 这是 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
}

我错误地认为系统会自动重新查询所有命令。它实际上做的是挂钩每个 Command 的 CanExecuteChanged 事件,而 RelayCommand 基本上将其 CanExecuteChanged 事件链接到 CommandManager 的 RequerySuggested 事件,因此每次系统“建议”重新查询时,实际上都是在重新查询我所有的 RelayCommands。

谢谢。

【讨论】:

  • 那么解决方案在哪里?
  • 为了什么?如果您不希望 RequerySuggested 事件重新查询您的命令,请不要使用 RelayCommand。
  • 不,我问这是否会造成性能问题。如果使用正确,它不会。这是大约 5 年前 :)
猜你喜欢
  • 1970-01-01
  • 2012-02-08
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 2019-02-09
  • 1970-01-01
  • 2018-12-30
相关资源
最近更新 更多