CommandManager.RequerySuggested如何工作?

And*_*nea 37 keyboard wpf mouse user-interface input

MSDN只说明了这一点

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

但是,我似乎无法找到任何关于它是如何工作的痕迹,我应该注意/避免等...它只是听取输入?(即:鼠标移动,按键等等)

geh*_*hho 47

我无法确切地告诉你听到的事件CommandManager.但是,我可以告诉您,在使用CommandManager与异步操作相关联时应该小心.当我CommandManager在我的ICommand实现中使用时遇到以下问题:

我有一个绑定到的按钮,ICommand它触发了一个增加值的异步操作.现在,如果值已达到某个限制,ICommand则应禁用按钮/ (即其CanExecute()方法应返回false).问题是:在单击按钮并且异步操作已经启动之后立即CommandManager调用我的CanExecute()方法.这种异步操作没多久,但它是足够长的时间来获得它的结果CommandManager的检查,使限制检查在CanExecute()用旧值来完成.因此,虽然实际达到了限制,但按钮仍保持启用状态.有趣的是,在你点击UI中的任何地方后,按钮现在被禁用了,因为再次CommandManager检查了ICommand一下,现在根据限制检查了新值.实际上,我认为在CommandManager点击按钮之后等待大约50ms,直到它执行了检查ICommand,但我不太确定.

我的解决方案是在收到异步操作的结果后立即通过调用ViewModel中的方法强制再次CommandManager检查.更新:请注意,必须在UI线程上调用此方法,否则它将无效!(感谢此评论的中间空间)ICommandCommandManager.InvalidateRequerySuggested

  • 应该注意,因为您正在运行异步调用,所以必须在UI线程中调用CommandManager.InvalidateRequerySuggested(),否则从个人经验来看,它什么都不做. (11认同)
  • 在我看来,在这种情况下,你不应该使用CommandManager.RequerySuggested作为CanExecuteChanged事件的SOLE触发器.显然,您的代码知道异步操作何时完成.它应该使用该完成来提升命令的CanExecuteChanged.可能是CommandManager.RequerySuggested有很好的想法,所以也许你应该另外使用它们. (4认同)

Sam*_*Sam 5

在这种情况下,.NET 参考源是您的朋友。尽管它的评论很差,但您仍然可以了解有关内部处理的一些想法。

在内部CommandDevice类中,您可以找到一个调用 InvalidateRequerySuggested 的方法 PostProcessInput。这个方法的名称假设 InvalidateRequerySuggested 方法在每个输入事件上被调用。我确信有进一步的处理和过滤,以便您的 CanExecute 方法实际上不会在每次调用 InvalidateRequerySuggested 时调用。