是否可以让 CommandManager 仅重新查询特定 WPF 命令而不是全部命令?

发布于 2024-08-26 08:54:11 字数 637 浏览 4 评论 0原文

我正在尝试为我的 MVVM 应用程序实现高度响应的 UI,因此我选择让所有命令处理程序在 BackgroundWorker 中自动执行,这样它们就不会阻塞 UI。

但同时,我不希望用户能够在后台执行相同的命令时执行该命令。解决方案似乎很明显:

  1. 当调用 Executed 处理程序时,让 CanExecute 处理程序返回 false
  2. 启动 BackgroundWorker 异步
  3. BackgroundWorker 完成,让 CanExecute 处理程序再次返回 true

问题是,我需要在步骤 1 后通知 WPF,并在步骤 3 后再次通知 WPF CanExecute 已更改并且应该需要它。我知道我可以通过调用 CommandManager.InvalidateRequerySuggested 来完成此操作,但这也会导致重新查询所有其他命令的 CanExecute 处理程序。有很多命令,这不好。

有没有一种方法可以要求重新查询特定命令 - 即当前正在执行的命令?

TIA

I'm trying to implement a highly responsive UI for my MVVM application, so I've chosen to have all command handlers automatically execute in a BackgroundWorker so they don't block the UI.

But at the same time, I don't want the user to be able to execute the same command while it is still executing in the background. The solution seems obvious:

  1. When Executed handler is invoked, have the CanExecute handler return false
  2. Start the BackgroundWorker async
  3. When BackgroundWorker finishes, have the CanExecute handler return true again.

Problem is, I need to notify WPF after step 1 and again after step 3 that CanExecute has changed and that it should be required. I know I can do it by calling CommandManager.InvalidateRequerySuggested, but that causes CanExecute handlers of all other commands to be requeried as well. Having a lot of commands, that's not good.

Is there a way to ask for requery of a specific command - i.e. the one that is currently being executed?

TIA

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月棠 2024-09-02 08:54:12

我认为你只需要提出 ICommand.CanExecuteChanged对于这两种情况,都会发生 事件,相应的控件应该更新其 IsEnabled 状态。

I think you only need to raise the ICommand.CanExecuteChanged event for these two cases, and the corresponding control should update its IsEnabled state.

‘画卷フ 2024-09-02 08:54:12

gehho 是对的,只需引发 CanExecuteChanged 事件即可。但老实说,我不知道你的实现,但如果你的 CanExecute 谓词很简单,我认为很难注意到 wpf 正在重新查询。我不敢相信您会注意到性能下降。你测试过性能吗?我的意思是,假设您在 ViewModel 中有 20 个 ICommand(这可能太多了),如果 ICommand.CanExecute 指向您根据后台工作程序设置为 true 和 false 的布尔字段,那么它应该花费不到纳秒的时间。但如果 CanExecute 指向一个求值的方法,那么它可能会更长,但我仍然怀疑它是否会引人注目。

但是嘿,我不知道你的实现。

gehho is right, just raise the CanExecuteChanged event. But honestly, I don't know your implementation, but if your CanExecute predicate is simple, I think it will be hard to notice that wpf is requerying. I can't believe you will notice a performance hit. Have you tested performance? I mean let's say you have 20 ICommands in a ViewModel(which is probably too much) if the ICommand.CanExecute points to a boolean field that you are setting to true and false based on the backgroundworker it should take less than nanoseconds. But if the CanExecute is pointed to a method that evaluates, then it may be longer, but I still doubt it would be noticeable.

But hey, I don't know your implementation.

情痴 2024-09-02 08:54:12

使用 MVVM Helper `DelegatingCommand',它为命令公开 RaiseCanExecuteChanged()。

因此,您可以订阅BackgroundWorker 上的RunWorkercompleted 事件,并根据记录的工作类型(也许您可以作为结果的一部分返回)从ViewModel 调用Command.RaiseCanExecuteChanged()

Use MVVM Helper's `DelegatingCommand' which exposes RaiseCanExecuteChanged() for the Command.

So you can subscribe to RunWorkercompleted event on BackgroundWorker and depending on the kind of work logged (maybe you can return as part of the Result) you call Command.RaiseCanExecuteChanged() from ViewModel.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文