为什么 CanxxxCommandExecute 被触发这么多次? [英] Why CanxxxCommandExecute is fired so much times?

查看:22
本文介绍了为什么 CanxxxCommandExecute 被触发这么多次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Commands 和它们的 CanXXXExecute 时遇到了一些问题...我以为这是 Catel(MVVM 框架)问题,但我已经使用标准 WPF 应用程序测试了自己,但它仍然发生..

I've got some problems with Commands and their CanXXXExecute... I was thinking it was a Catel (MVVM framework) problem but I've tested myself with a standard WPF application and it still happen..

在我发布的示例中,我在加载时调用了 2 次CanClickCommandExecute"方法(一个在构造函数中,我同意这一点,另一个我认为是在视图的加载中)和 3 次单击按钮!!

In the example I'm posting I've got the "CanClickCommandExecute" method called 2 times at load (one at constructor and I agree with this, the other one I think at view's load) and 3 times when I click the button!!

这是 XAML

<Window x:Class="StandardWPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Button Command="{Binding ClickCommand}" Content="ClickMe!" Background="Teal"></Button>
</Grid>

.cs

public partial class MainWindow : Window
{

    public ICommand ClickCommand { get; private set; }
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        ClickCommand = new RelayCommand(OnClickCommandExecute,CanClickCommandExecute);
    }

    private bool CanClickCommandExecute()
    {
        Debug.WriteLine("Standard OnClickCommandExecute fired!");
        return true;
    }

    private void OnClickCommandExecute()
    {
      //something weird in there!
    }
}

RelayCommand(取自 这里)

The RelayCommand (taken from here)

public class RelayCommand : ICommand
{
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    private Action methodToExecute;
    private Func<bool> canExecuteEvaluator;
    public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
    {
        this.methodToExecute = methodToExecute;
        this.canExecuteEvaluator = canExecuteEvaluator;
    }
    public RelayCommand(Action methodToExecute)
        : this(methodToExecute, null)
    {
    }
    public bool CanExecute(object parameter)
    {
        if (this.canExecuteEvaluator == null)
        {
            return true;
        }
        else
        {
            bool result = this.canExecuteEvaluator.Invoke();
            return result;
        }
    }
    public void Execute(object parameter)
    {
        this.methodToExecute.Invoke();
    }
}

为什么会这样?我怎样才能发现发生了什么?在我的真实案例中,我使用 CanXXX 来执行验证……在这种情况下,我多次触发验证,并且在某些对象上可能需要很多时间

Why this happen? How can I spot what's happening? In my real case I use the CanXXX to perform validation...in that case I got validation fired a lot of times and on some object can take a lot of time

推荐答案

为什么 CanxxxCommandExecute 被触发这么多次?

Why CanxxxCommandExecute is fired so much times?

因为你多次提升 CanExecuteChanged 方法,所以 CanExecute 被 wpf 评估了几次.

Because you're raising the CanExecuteChanged method several times, and so CanExecute is evaluated by wpf several times.

您不是自己直接引发事件,而是 CommandManager.RequerySuggested 做到了.

You're not directly raising the event yourself, but CommandManager.RequerySuggested does it.

正如文档所说在 CommandManager 检测到可能改变命令执行能力的条件时发生. CommandManager.RequerySuggested 将猜测可能需要的事件更新按钮的状态.它可能会发生很多次,例如最小化应用程序会触发它;等

As the documentation says Occurs when the CommandManager detects conditions that might change the ability of a command to execute. CommandManager.RequerySuggested will guess the possible events which might need to update the button's state. It may happen many times, for instance minimizing the app will trigger it; etc.

如果您想控制 CanExecute 的调用时间,请手动引发事件.不要使用 CommandManager.RequerySuggested.

If you want to take control over when CanExecute is called, then raise the event manually. Don't use CommandManager.RequerySuggested.

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

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