如何防止 CommandManager 在有 UI 交互时调用 CanExecute
本文关键字:调用 CanExecute 交互 UI 何防止 CommandManager 在有 | 更新日期: 2023-09-27 18:37:13
我们的UI目前有很多控件绑定到具有一些复杂CanExecutes
的命令。我们面临的问题是,每当CommandManager
确定需要重新评估UI时,所有命令都会运行其CanExecute
,这反过来又会导致特定场景的性能下降。
阅读这篇文章:CommandManager.RequerySuggest如何工作?
似乎CommandManager
将重新评估简单的按键按下、鼠标移动事件等。有没有办法防止这种情况发生,而是让命令管理器在手动调用时重新评估?
解决方案可能是实现 RelayCommand
类的更简单版本,该版本仅存储事件处理程序本身,并公开一个公共方法来在适当时触发它们:
public class RelayCommand : ICommand
{
public event EventHandler CanExecuteChanged;
// Further ICommand implementation omitted...
public void Invalidate()
{
var handler = this.CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
然后,在视图模型中调用以下命令以重新评估该命令:
fooCommand.Invalidate();
当然,这给您留下了相反的问题,您现在必须手动重新评估所有命令......
编辑
为了详细说明注释,大多数RelayCommand
都像这样实现CanExecuteChanged
事件:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
当 UI 订阅命令的 CanExecuteChanged
事件时,它实际上是间接订阅了 CommandManager.RequerySuggested
事件,这就是为什么每次CommandManager
建议重新查询时都会调用 CanExecute
方法的原因。
我建议的更简单RelayCommand
通过不订阅CommandManager.RequerySuggested
事件来避免此问题。