除非单击鼠标,否则 Button 不会重新启用的奇怪问题 [英] Weird problem where Button does not get re-enabled unless the mouse is clicked

查看:14
本文介绍了除非单击鼠标,否则 Button 不会重新启用的奇怪问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序是使用 WPF 中的 MVVM 模式编写的,我的所有按钮都使用命令绑定来执行我的模型中的代码.所有命令在 CanExecute 中都有代码来确定绑定按钮的启用状态.该逻辑运行良好,但在所有情况下,除非我单击 GUI 中的其他位置,否则 GUI 将保持禁用状态.

My app is written using the MVVM pattern in WPF, and all of my Buttons use Command bindings to execute code in my model. All commands have code in CanExecute to determine the bound Button's Enabled state. The logic works perfectly, but in all cases, the GUI remains in a disabled state unless I click somewhere else in the GUI.

例如,我有一个名为 Discard Candy 的按钮.当我单击此按钮时,它会在线程池线程中启动一个进程,该进程将名为 Running 的 bool 属性设置为 true.由于丢弃糖果命令的 CanExecute 方法看起来像这样

For example, I have a button called Discard Candy. When I click this button, it launches a process in a threadpool thread, which sets a bool property called Running to true. Since the CanExecute method for Discard Candy's command looks something like this

public bool CanExecute(object parameter)
{
  return !Running;
}

一旦进程开始,该按钮将被禁用.问题是,当该过程完成后,正在运行被设置为 false,但 GUI 不会更新,即不会重新启用丢弃糖果.

the button will be disabled once the process starts. The problem is that when the process is done, Running gets set to false, but the GUI doesn't update, i.e. Discard Candy doesn't get re-enabled.

但是,如果我单击 GUI 中的任何位置,例如在窗口或标题栏上,放弃糖果"按钮会突然启用.所以逻辑有效,但发生了一些我不明白的事情.有人可以向我解释这种行为吗?

However, if I click anywhere in the GUI, like on the window or title bar, the Discard Candy button all of a sudden gets enabled. So the logic works, but something is going on that I just don't understand. Can someone please explain this behavior to me?

EDIT -- 到目前为止,听起来 CommandManager.InvalidateRequerySuggested 并没有帮助人们.我打算试一试,但目前我有点担心.我确实遵循了推荐的链接,因此决定阅读有关 MVVM 轻型工具包的更多信息.这听起来非常不错——这里有没有人使用过它并且能够确认它没有出现我目前看到的问题?尽管我计划在下一个主要版本中尝试使用 MVVM 轻型工具包.在我的应用程序中,我不想重做我目前拥有的所有命令,这就是为什么我可能会从 CommandManager.InvalidateRequerySuggested 开始,这样我们都可以在这里获得另一个关于它有用性的数据点.

EDIT -- so far, it sounds like CommandManager.InvalidateRequerySuggested hasn't helped people. I am going to give it a shot, but at the moment am a little wary of it. I did follow the recommended links, and in doing so decided to read more about the MVVM light toolkit. It sounds very nice -- has anyone here used it and been able to confirm that it does not exhibit the problem I've been seeing so far? Although I plan to try the MVVM light toolkit in the next major rev. of my application, I don't want to redo all of the commanding that I currently have in place, which is why I'll likely start with CommandManager.InvalidateRequerySuggested so we can all get another data point here regarding it's usefulness.

EDIT #2 -- 非常有趣,MVVM 轻型工具包实际上依赖 CommandManager.InvalidateRequerySuggested 以支持 UI 禁用/重新启用命令的能力.作者说:

EDIT #2 -- very interesting, the MVVM light toolkit actually relies on CommandManager.InvalidateRequerySuggested in order to support the UI's ability to disable / re-enable commands. The author says:

严格来说,在 WPF 中,如果您的命令绑定到由 CommandManager 监视的控件,则您不必自己引发 CanExecuteChanged 事件.您可以让 CommandManager 处理这种情况.也就是说,外部事件也可能会改变 UI 的状态.让我们想象一下,应该从上午 9 点到下午 5 点启用 UI,然后在晚上禁用.用户没有触发 UI,因此代码应该(礼貌地)请求 CommandManager重新查询命令的状态.这是通过调用 CommandManager 上的 InvalidateRequerySuggested 方法完成的.正如您所猜到的,RelayCommand 类的 RaiseCanExecuteChanged 方法就是这样做的."

"Strictly speaking, in WPF, and if your command is bound to a control that is watched by the CommandManager, you shouldn’t have to raise the CanExecuteChanged event yourself. You can let the CommandManager handle the situation. That said, external events might also change the state of the UI. Let’s imagine that the UI should be enabled from 9AM to 5PM, and then disabled for the night. The user is not triggering the UI, so the code should request (politely) that the CommandManager requeries the state of the commands. This is done by calling the method InvalidateRequerySuggested on the CommandManager. And as you guessed, the method RaiseCanExecuteChanged of the RelayCommand class does just that."

推荐答案

WPF 不会更新命令绑定控件,除非它有理由这样做.单击 GUI 会导致 WPF 刷新,以便更新生效.

WPF doesn't update command bound controls unless it has a reason to. Clicking on the GUI causes WPF to refresh so the update then works.

您可以通过调用 CommandManager.InvalidateRequerySuggested.

You can manually cause a refresh of any command bound controls by calling CommandManager.InvalidateRequerySuggested.

这篇关于除非单击鼠标,否则 Button 不会重新启用的奇怪问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆