Command 中连续调用 CanExecute 的性能损失

发布于 2024-10-05 09:10:16 字数 173 浏览 9 评论 0原文

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

谢谢。

I am applying the MVVM pattern to a project. I have a UserControl that has a button which is bound to a command exposed by the ViewModel.
Since the button is visible, it's calling continuously the CanExecute method of the button. Something tells me that this carries a performance penalty, but I'm not sure. Is this the expected behavior? or is there a better way of having a button bound to a command?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最偏执的依靠 2024-10-12 09:10:16

抱歉,我知道发生了什么事。
这是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 事件,因此每次系统“建议”重新查询时,它实际上是在重新查询我的所有 RelayCommand。

谢谢。

Sorry, I found out what was happening.
This is the implementation of 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
}

I had incorrectly assumed the system was requerying ALL commands automatically. What it actually does is hook to each Command's CanExecuteChanged event, and RelayCommand basically links its CanExecuteChanged event to the CommandManager's RequerySuggested event, so each time the system "suggests" a requery, it was in fact requerying all my RelayCommands.

Thank you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文