我正在尝试为我的MVVM应用程序实现高度响应的UI,所以我选择让所有命令处理程序在BackgroundWorker
中自动执行,这样它们就不会阻止UI。
但与此同时,我不希望用户在后台执行时仍能执行相同的命令。解决方案似乎显而易见:
Executed
处理程序时,让CanExecute
处理程序返回false
BackgroundWorker
async BackgroundWorker
完成后,让CanExecute
处理程序再次返回true
。问题是,我需要在步骤1之后通知WPF,并在步骤3之后再次通知CanExecute
已经发生变化并且需要它。我知道我可以通过调用CommandManager.InvalidateRequerySuggested
来执行此操作,但这会导致所有其他命令的CanExecute
处理程序也被重新查询。有很多命令,这不好。
有没有办法要求重新查询特定命令 - 即当前正在执行的命令?
TIA
答案 0 :(得分:6)
我认为您只需针对这两种情况提出ICommand.CanExecuteChanged事件,相应的控件应该更新其IsEnabled
状态。
答案 1 :(得分:1)
gehho是对的,只是举起CanExecuteChanged事件。但老实说,我不知道你的实现,但如果你的CanExecute谓词很简单,我认为很难注意到wpf正在重新查询。我无法相信你会注意到性能受到打击。你测试过性能吗?我的意思是假设你在ViewModel中有20个ICommands(这可能太多了),如果ICommand.CanExecute指向一个布尔字段,你设置为true和false,基于后台工作者它应该花费不到纳秒。但是如果CanExecute指向一个评估的方法,那么它可能会更长,但我仍然怀疑它会引人注意。
但是,嘿,我不知道你的实施。
答案 2 :(得分:1)
使用MVVM Helper's`DelegatingCommand'为命令公开RaiseCanExecuteChanged()。
因此,您可以在BackgroundWorker上订阅RunWorkercompleted事件,并根据记录的工作类型(可能您可以作为结果的一部分返回)从ViewModel调用Command.RaiseCanExecuteChanged()
。