【问题标题】:Programatic re-evaluation of MVVM command's "can execute" stateMVVM 命令“canexecute”状态的程序化重新评估
【发布时间】:2011-02-28 09:53:31
【问题描述】:

我正在使用 MVVM 模式编写 WPF 应用程序,基于以下文章:WPF Apps With The Model-View-ViewModel Design Pattern

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

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

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

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

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

【问题讨论】:

    标签: wpf mvvm command relaycommand


    【解决方案1】:

    您可以在 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()。必要时使用 Dispatcher 进行调用。

    【讨论】:

    • 这与我最初的猜测是一样的,但是,出于某种我不知道的原因,它似乎不起作用。每次程序的状态(如 Idle、Working、PendingStop 等)发生变化时,我都会调用这个静态方法(“CommandManager.InvalidateRequerySuggested”),只有这个 state 属性在 canExecute 处理程序中使用。尽管如此,它似乎不起作用(尽管我同意它应该)。顺便说一句,去检查 ICommand 实现,它在我之前引用的文章中,图 3。
    • 是的,它确实取决于 ICommand 的实现方式。我已经更新了我的答案,详细说明了如何在 Prism 中重新查询 CanExecute。我会看你关注的文章。
    • 这可能与在非 UI 线程上执行 InvalidateRequerySuggested() 有关吗?尝试使用 Dispatcher 调用它,以便在 UI 线程上调用它。
    • 好电话,我将尝试使用调度程序调用它。
    • 如果 InvalidateRequerySuggested() 仅适用于 UI 线程,文档不应该这么说吗(它没有)?对于实现来说,将调用推送到 UI 线程肯定很容易——对于 100 个客户端每个都通过 Dispatcher 进行调用而不是让一个 CommandManager 实现来做这件事是没有意义的。
    猜你喜欢
    • 2016-12-20
    • 2023-03-25
    • 2017-04-07
    • 2021-11-08
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多