MVVM命令的"可执行"状态的编程重新评估

dzs*_*dzs 10 wpf command mvvm relaycommand

我正在使用MVVM模式编写WPF应用程序,基于以下文章:使用Model-View-ViewModel设计模式的WPF应用程序

我的View上有两个按钮,按钮的"Command"属性绑定(带数据绑定)到RelayCommand类的给定实例(参见上面文章中的"图3 RelayCommand类").RelayCommand类支持检查是否可以执行给定的命令.

WPF会自动禁用无法执行命令的按钮.

我的每个命令(在ViewModel类中)都启动后台操作,并且在后台操作完成之前无法再次执行该命令.RelayCommand实例具有后台操作是否仍在工作或已完成的信息.

我的问题如下:按下任意一个按钮后,按钮自动被禁用(这是正常的),因为后台操作已经开始,命令在完成之前无法执行,但是在操作完成后,按钮不会不会自动启用,因为它们的命令"可以执行"谓词不会自动重新评估.通过让应用程序松散并重新获得焦点(通过按ALT + TAB)可以手动触发重新评估.完成此操作后,按钮再次启用.

我怎样才能以编程方式重新评估按钮命令的"可以执行"状态?

Tim*_*oyd 20

您可以在CommandManager上调用InvalidateRequerySuggested来通知应该重新查询CanExecute:

CommandManager.InvalidateRequerySuggested();
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx

这取决于特定ICommand实现是否已正确实现ICommand.CanExecuteChanged模式,因此YMMV.

更新

例如,我使用Prism,它有自己的基本实现ICommand:DelegateCommand.我发现在Prism的DelegateCommand上调用RaiseCanExecuteChanged()为我工作.

更新2

并确保在UI线程上调用InvalidateRequerySuggested().如有必要,请使用Dispatcher进行呼叫.

  • 如果InvalidateRequerySuggested()仅适用于UI线程,那么文档是否应该说(它没有)?对于实现来说,将调用推送到UI线程当然是很容易的 - 对于100个客户端来说,通过Dispatcher进行调用而不是让一个CommandManager实现这样做是没有意义的. (2认同)