强制重新评估ICommand.CanExecute

时间:2015-11-11 09:37:05

标签: c# wpf

在WPF XAML中,我有一个Button的{​​{1}}属性正在使用实现Command的类的实现。

在此实现中,我ICommand事件连接起来使用CanExecuteChanged - 我希望能够控制何时调用CanExecute,并使用此功能不必要地调用它。

我可以让CommandManager.RequerySuggested重新评估的另一种方法是使用类似的东西:

ICommand.CanExecute

在我的班级中实施public void InvokeCanExecute() { CanExecuteChanged.Invoke(this, new EventArgs()); }

这看起来真的很讨厌 - 我错过了一些明显的东西吗?我尝试使用ICommand调用重新评估,但这似乎不起作用。

2 个答案:

答案 0 :(得分:1)

不,你真的没有遗漏任何东西。这是一个类似的问题,建议您采用相同的方法:What is the actual task of CanExecuteChanged and CommandManager.RequerySuggested?

您可以使您的方法更加健壮:

public void InvokeCanExecute()
{
    var handler = CanExecuteChanged;
    if (handler != null)
    {
        handler(this, new EventArgs());
    }
}

答案 1 :(得分:1)

确实如此 - 如果您不想使用CommandManager.RequerySuggested,确实可能更频繁地调用CanExecute - 您需要按顺序显式调用自己的InvokeCanExecute方法强制命令重新评估其CanExecute条件。

但是,在大多数情况下,CanExecute条件将取决于公共(可绑定)属性,这意味着引发PropertyChanged事件以指示其值已更改的属性 - 可以挂钩event,以便在命令所依赖的某个属性发生更改时自动调用InvokeCanExecute。有关如何实现此类命令的示例,请参阅this guy's blog post(如果我没有记错,这种方法是作为 MVVM Light 工具包的一部分实现的。)

使用此方法实例化命令看起来如下所示:

SaveCommand = new RelayCommand(() => { /* do some stuff; */ }, 
                               () => !string.IsNullOrEmpty(Name), 
                               this, () => Name);

由于命令的CanExecute条件(检查Name是否为空)取决于Name属性,因此只要Name的内容需要重新评估它变化。您只需将对Name属性的引用传递给命令的构造函数,只要InvokeCanExecute的值发生更改,就会自动调用Name

理论上,可以更进一步,让命令本身检查它所依赖的属性 - 如果你对这种方法感兴趣,请查看 one of my blog articles,但请注意,这一点在很大程度上取决于反射,所以它总是取决于详细的用例 - 这种方法是否可行。此解决方案的示例实现包含在the MVVMbasics framework中(免责声明:由我发布)。在这种情况下,您可以将命令初始化代码减少为:

SaveCommand = CreateRelayCommand(() => { /* do some stuff; */ }, 
                                () => !string.IsNullOrEmpty(Name));