在什么情况下ICommand CanExecute可能不会更新?

And*_*ens 2 wpf

多年来,我一直在几个大型项目中使用Josh Smith的RelayCommand实现.但是今天我遇到了一个场景,其中我的一个命令上的CanExecute没有刷新.我不知道是什么造成了它 - 视图模型没有做任何我已经做过几十次的事情.

VM的构造函数创建了几个命令.第一个是"开始"命令: -

StartCommand = new RelayCommand(o => StartAsync(), o => true);
Run Code Online (Sandbox Code Playgroud)

StartAsync()方法如下所示: -

private async void StartAsync()
{
    IsRunning = true;
    await Task.Run(() => SomeLongRunningProcess(); }
    IsRunning = false;
}
Run Code Online (Sandbox Code Playgroud)

还有一个"保存"命令: -

SaveCommand = new RelayCommand(o => Save(), o => !IsRunning);
Run Code Online (Sandbox Code Playgroud)

('IsRunning'是一个bog标准属性,实现了INotifyPropertyChanged.除了用于"CanExecute"委托之外,它还绑定到视图中几个控件的IsEnabled属性以启用/禁用它们).

当我单击"开始"按钮(绑定到"StartCommand")时,"保存"按钮被正确禁用.b/g进程运行完成,然后将IsRunning设置为false,但这不会触发"保存"按钮以启用.它只有在我点击视图的某个位置时才会启用.

(其控件IsEnabled属性绑定到虚拟机IsRunning性能能够正确地禁用,顺便说一句).

我有一些关于这个的SO文章,但没有真正解释为什么会发生这种情况.我的解决方法是将按钮的IsEnabled属性绑定到'IsRunning',但令人沮丧的是这个特定视图拒绝播放.关于可能导致这种情况的任何想法?常识说它是特定于这个视图/ VM的东西,但我很难过(我不打算在这里发布代码 - 它有太多了).

Sri*_*vel 5

是的,因为您使用的RelayCommand版本取决于CommandManager.RequerySuggested事件而且不准确.

文件说明了这一点

在CommandManager检测到可能会更改命令执行能力的条件时发生.

基本上它会猜测可以更改数据的所有可能事件.它永远不会知道您的ViewModel/Model何时被更改.它没有收听房产变更通知.

如果您想立即做出反应而无需等待CommandManager猜测,则需要在ICommand.CanExecuteChanged更新模型时自行手动触发.

您看到事件没有被触发,除非您单击窗口或其他东西,但请注意它也可能会多次触发