我们的UI目前有很多控件绑定到一些复杂CanExecutes
的命令。我们面临的问题是,只要CommandManager
确定需要重新评估UI,所有命令都会运行CanExecute
,这反过来会对特定情况造成相当大的性能损失。
阅读这篇文章:How does CommandManager.RequerySuggested work?
似乎CommandManager
将在简单的按键,鼠标移动事件等方面重新进行评估。有没有办法防止这种情况发生,而是在手动调用时让命令管理器重新评估?
答案 0 :(得分:1)
解决方案可能是实现一个简单版本的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);
}
}
}
然后在viewModel中调用以下命令重新评估命令:
fooCommand.Invalidate();
当然,这会让您遇到相反的问题,即您现在必须手动重新评估所有命令......
修改强>
要详细说明评论,大多数RelayCommand
都会像这样实施CanExecuteChanged
事件:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
当UI订阅命令的CanExecuteChanged
事件时,它实际上间接订阅了CommandManager.RequerySuggested
事件,这就是每次CanExecute
时调用CommandManager
方法的原因建议重新查询。
我建议的更简单的RelayCommand
通过不订阅CommandManager.RequerySuggested
事件来避免此问题。