我有一个Menu
,每个MenuItem
的层次结构的Command
属性设置为一个RoutedCommand
我定义。 相关联CommandBinding
提供了用于评价的回调CanExecute
控制每个的启用状态MenuItem
。
这几乎工程。 菜单项初步拿出了正确的启用和禁用状态。 然而,当我的数据CanExecute
回调使用的变化,我需要的命令从我的回调,以便重新请求的结果为这个新状态反映在UI。
似乎没有要任何公共方法RoutedCommand
或CommandBinding
这一点。
需要注意的是回调再次使用,当我点击或输入到控制(我想这是触发输入,因为鼠标悬停不会导致刷新)。
不是最漂亮的书,但你可以使用CommandManager所有无效的CommandBinding:
CommandManager.InvalidateRequerySuggested();
查看更多信息MSDN
对于任何人谁遇到这个版本; 如果你碰巧使用MVVM和棱镜,然后棱镜的DelegateCommand
实现ICommand
提供.RaiseCanExecuteChanged()
方法来做到这一点。
我不能用CommandManager.InvalidateRequerySuggested();
因为我得到的性能损失。
我已经使用MVVM助手的委派命令,它看起来像下面(我已经调整了它一下我们的REQ)。 你必须调用command.RaiseCanExecuteChanged()
从VM
public event EventHandler CanExecuteChanged
{
add
{
_internalCanExecuteChanged += value;
CommandManager.RequerySuggested += value;
}
remove
{
_internalCanExecuteChanged -= value;
CommandManager.RequerySuggested -= value;
}
}
/// <summary>
/// This method can be used to raise the CanExecuteChanged handler.
/// This will force WPF to re-query the status of this command directly.
/// </summary>
public void RaiseCanExecuteChanged()
{
if (canExecute != null)
OnCanExecuteChanged();
}
/// <summary>
/// This method is used to walk the delegate chain and well WPF that
/// our command execution status has changed.
/// </summary>
protected virtual void OnCanExecuteChanged()
{
EventHandler eCanExecuteChanged = _internalCanExecuteChanged;
if (eCanExecuteChanged != null)
eCanExecuteChanged(this, EventArgs.Empty);
}
如果您已经推出自己的类,它实现ICommand
,你可以失去很多逼你自动状态更新的依靠手工刷新超过应是必要的。 它也可以打破InvalidateRequerySuggested()
问题是,一个简单ICommand
实现不新命令链接到CommandManager
。
解决的办法是使用以下命令:
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
这样,用户连接到CommandManager
,而不是你的类可以适当参与指挥状态的变化。
我已经实现了一个解决方案来处理命令财产的依赖性,这里的链接https://stackoverflow.com/a/30394333/1716620
感谢你会最终有一个像这样的命令:
this.SaveCommand = new MyDelegateCommand<MyViewModel>(this,
//execute
() => {
Console.Write("EXECUTED");
},
//can execute
() => {
Console.Write("Checking Validity");
return PropertyX!=null && PropertyY!=null && PropertyY.Length < 5;
},
//properties to watch
(p) => new { p.PropertyX, p.PropertyY }
);
这是对我工作:在XAML命令之前把CanExecute。
文章来源: WPF - How to force a Command to re-evaluate 'CanExecute' via its CommandBindings