我的应用程序是使用 WPF 中的 MVVM 模式编写的,并且我的所有按钮都使用命令绑定(bind)来执行模型中的代码。所有命令在 CanExecute 中都有代码来确定绑定(bind)的 Button 的 Enabled 状态。该逻辑运行良好,但在所有情况下,除非我单击 GUI 中的其他位置,否则 GUI 仍处于禁用状态。
例如,我有一个名为 Discard Candy 的按钮。当我单击此按钮时,它会在线程池线程中启动一个进程,该进程将名为 Running 的 bool 属性设置为 。真实 .由于 Discard Candy 命令的 CanExecute 方法看起来像这样
public bool CanExecute(object parameter)
{
return !Running;
}
一旦进程开始,该按钮将被禁用。问题是当进程完成时,Running 被设置为 。假 ,但 GUI 不会更新,即 Discard Candy 不会重新启用。
但是,如果我单击 GUI 中的任意位置,例如窗口或标题栏,则 Discard Candy 按钮会突然启用。所以逻辑有效,但发生了一些我不明白的事情。有人可以向我解释这种行为吗?
编辑 -- 到目前为止,听起来 CommandManager.InvalidateRequerySuggested 并没有帮助人们。我打算试一试,但目前我有点警惕。我确实遵循了推荐的链接,因此决定阅读更多关于 MVVM 轻量级工具包的信息。听起来很不错——这里有没有人使用过它并且能够确认它没有出现我迄今为止看到的问题?虽然我计划在下一个主要版本中尝试 MVVM 轻量级工具包。在我的应用程序中,我不想重做我目前拥有的所有命令,这就是为什么我可能会从 CommandManager.InvalidateRequerySuggested 开始,这样我们就可以在这里获得另一个关于它有用性的数据点。
编辑#2 -- 很有意思,MVVM 轻量级工具包居然 依赖 在 CommandManager.InvalidateRequerySuggested 上,以支持 UI 禁用/重新启用命令的能力。作者说:
“严格来说,在 WPF 中,如果您的命令绑定(bind)到由 CommandManager 监视的控件,则您不必自己引发 CanExecuteChanged 事件。您可以让 CommandManager 处理这种情况。也就是说,外部事件可能还要更改 UI 的状态。假设 UI 应该从上午 9 点到下午 5 点启用,然后在晚上禁用。用户没有触发 UI,因此代码应该(礼貌地)请求 CommandManager 请求状态的命令。 这是通过调用 CommandManager 上的 InvalidateRequerySuggested 方法来完成的。正如您猜到的,RelayCommand 类的 RaiseCanExecuteChanged 方法就是这样做的。"
请您参考如下方法:
我的问题似乎与命令绑定(bind)有关 - 我使用了 RelayCommand
就像我经常做的那样,但是在我单击一个窗口之前,按钮的呈现是不正确的。
删除 CanExecute
来自 CommandBinding
的代码并使用 IsEnabled
属性(property)反而解决了我的问题而没有头疼-直到我在许多其他可能是问题的事情中尝试了这一点才花了很长时间。