以编程方式重新评估 MVVM 命令的“可以执行”状态

发布于 2024-09-04 06:09:34 字数 597 浏览 2 评论 0原文

我正在使用 MVVM 模式编写一个 WPF 应用程序,基于以下文章: WPF使用模型-视图-视图模型设计模式的应用程序

我的视图上有两个按钮,按钮的“Command”属性绑定(通过数据绑定)到 RelayCommand 类的给定实例(参见“图 3 RelayCommand类”来自上面的文章)。 RelayCommand 类支持检查给定命令是否可以执行。

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

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

我的问题如下:按下任何按钮后,按钮会自动禁用(这是可以的),因为后台操作已启动,并且命令在完成之前无法执行,但操作完成后,按钮不可用不会自动启用,因为它们的命令的“可以执行”谓词不会自动重新评估。可以通过松开应用程序并重新获得焦点(按 ALT+TAB)来手动触发重新评估。完成此技巧后,按钮将再次启用。

如何以编程方式重新评估按钮命令的“可以执行”状态?

I'm writing a WPF application using the MVVM pattern, based on the following article: WPF Apps With The Model-View-ViewModel Design Pattern

I have two buttons on my View with the buttons' "Command" property bound (with data binding) to a given instance of the RelayCommand class (see "Figure 3 The RelayCommand Class" from the article above). The RelayCommand class has support for checking whether the given command can be executed.

WPF automatically disables buttons whose command cannot be executed.

Each of my commands (in the ViewModel class) start a background operation, and the command cannot be executed again until the background operation is finished. The RelayCommand instances have information whether the background operation is still working or it is finished.

My problem is the following: after pressing the any of the buttons, the buttons automaticaly go disabled (which is OK) because the background operation started and the command cannot be executed until it is finished, but after the operation had finished, the buttons don't go enabled automatically because their command's "can be executed" predicate is not automatically reevaluated. The reevaluation can be manually triggered by having the application loose and regain focus (by pressing ALT+TAB). After doing this trick, the buttons get enabled once again.

How can I programatically reevaluate the buttons' command's "can execute" state?

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

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

发布评论

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

评论(1

不羁少年 2024-09-11 06:09:34

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

CommandManager.InvalidateRequerySuggested();

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()。如有必要,请使用调度程序进行呼叫。

You can call InvalidateRequerySuggested on the CommandManager to notify that CanExecute should be re-queried:

CommandManager.InvalidateRequerySuggested();

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

This does depend on whether the particular ICommand implementation has properly implemented the ICommand.CanExecuteChanged pattern, so YMMV.

Update

For instance, I use Prism which has it's own base implementation ICommand: DelegateCommand. I find that calling RaiseCanExecuteChanged(), on a DelegateCommand in Prism work for me.

Update 2

And make sure that you are calling InvalidateRequerySuggested() on the UI thread. Use the Dispatcher if necessary to make the call.

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