我刚刚将一个项目从Catel 3.4更新为Catel 4.0,并且一个自定义的应用按钮一直在工作,现在从未启用过。
AddCustomButton(new DataWindowButton("Apply", ExecuteApply, canExecuteApply));
在Catel 3.4中,当窗口获得焦点或更改了任何控件时,canExecuteApply被调用。在4.0中,创建窗口时会调用两次,而不会再次调用。
我怀疑这与更新指南的IViewPropertySelector部分有关,但是注册默认实现无效,并且我无法弄清楚AutoDetectViewPropertiesToSubscribe扩展方法所在的名称空间。
编辑:我发现我在应用程序中的其他地方出现了与某些AsynchronousCommand实例相同的行为。创建控件后,CanExecute委托将触发,然后不再触发。
编辑2:这些是不同解决方案的相同问题。有关此问题的说明,请参阅Geert van Horrik的答案。
如果命令已在视图模型中注册,则可以使用
ViewModelCommandManager.InvalidateCommands(true);
以获得可以执行的状态进行重新评估。对于如上所述的DataWindowButton,我不得不在按钮的命令上手动调用RaiseCanExecuteChanged,因为据我所知,该命令不属于vie模型。
var catelCommand = (applyButton.Command as ICatelCommand);
if (catelCommand != null)
{
catelCommand.RaiseCanExecuteChanged();
}
无论哪种情况,这都不是具有最佳性能特征的方法,但是如果需要与升级之前相同的行为,则可以在以下事件订阅中进行这些调用:
System.Windows.Input.CommandManager.RequerySuggested += RequerySuggested;
希望这对其他面临此问题的人有所帮助。
最佳答案
原因是过去(4.0之前),Catel订阅了WPF的CommandManager,并使几乎所有内容(鼠标移动,焦点等)上所有视图模型上的所有命令均无效。为了提高性能(很多),我们决定仅在属性在特定视图模型上更改时自动使命令无效。
例如,如果您有一个在其中更改属性的虚拟机,它将自动重新评估该虚拟机上的命令。您仍然可以使用以下代码(在vm内部)手动重新评估命令:
ViewModelCommandManager.InvalidateCommands(true);