每当有 UI 交互时,如何防止 CommandManager 调用 CanExecute?
How to prevent CommandManager from invoking CanExecute whenever there is UI interaction?
我们的 UI 目前有很多控件绑定到一些复杂的命令 CanExecutes
。我们面临的问题是,每当 CommandManager
确定 UI 需要重新评估时,所有命令 运行 他们的 CanExecute
,这反过来会导致相当大的性能针对特定场景命中。
阅读此 post:How does CommandManager.RequerySuggested work?
似乎 CommandManager
会在简单的按键按下、鼠标移动事件等时重新评估。有没有办法防止这种情况发生,而是让命令管理器在什么时候重新评估手动调用?
一个解决方案可能是实现一个更简单的 RelayCommand
class 版本,它只存储事件处理程序本身并公开一个 public 方法以在适当的时候触发它们:
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
事件来避免这个问题。
我们的 UI 目前有很多控件绑定到一些复杂的命令 CanExecutes
。我们面临的问题是,每当 CommandManager
确定 UI 需要重新评估时,所有命令 运行 他们的 CanExecute
,这反过来会导致相当大的性能针对特定场景命中。
阅读此 post:How does CommandManager.RequerySuggested work?
似乎 CommandManager
会在简单的按键按下、鼠标移动事件等时重新评估。有没有办法防止这种情况发生,而是让命令管理器在什么时候重新评估手动调用?
一个解决方案可能是实现一个更简单的 RelayCommand
class 版本,它只存储事件处理程序本身并公开一个 public 方法以在适当的时候触发它们:
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
事件来避免这个问题。