【问题标题】:Force reevaluate ICommand CanExecute upon context menu open在上下文菜单打开时强制重新评估 ICommand CanExecute
【发布时间】:2013-08-15 20:57:19
【问题描述】:
我知道我可以在视图模型中强制重新评估 CanExecute,但是,这需要视图模型注册到所有相关的数据更改事件,这可能并不总是可行的。
由于命令仅在上下文菜单中使用,并且在上下文菜单打开期间,无法更改影响 CanExecute 的数据,因此仅在打开上下文菜单时重新评估 CanExecute 就足够了。
为此,我可以连接上下文菜单打开事件并调用视图模型以在上下文菜单使用的每个 ICommand 上调用 RaiseCanExecuteChanged,但这很乏味且反 MVVM。我想知道是否有更简单的方法来实现这一点?
【问题讨论】:
标签:
wpf
commandbinding
canexecute
【解决方案1】:
是的,有。使用 ICommand 的这个实现。它会重新评估每次交互,在您的情况下为“上下文菜单打开”。它的性能效率不高,但如果您没有数百个命令,那么应该完成这项工作:
public class Command<TArgs> : ICommand
{
public Command(Action<TArgs> exDelegate)
{
_exDelegate = exDelegate;
}
public Command(Action<TArgs> exDelegate, Func<TArgs, bool> canDelegate)
{
_exDelegate = exDelegate;
_canDelegate = canDelegate;
}
protected Action<TArgs> _exDelegate;
protected Func<TArgs, bool> _canDelegate;
#region ICommand Members
public bool CanExecute(TArgs parameter)
{
if (_canDelegate == null)
return true;
return _canDelegate(parameter);
}
public void Execute(TArgs parameter)
{
if (_exDelegate != null)
{
_exDelegate(parameter);
}
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
bool ICommand.CanExecute(object parameter)
{
if (parameter != null)
{
var parameterType = parameter.GetType();
if (parameterType.FullName.Equals("MS.Internal.NamedObject"))
return false;
}
return CanExecute((TArgs)parameter);
}
void ICommand.Execute(object parameter)
{
Execute((TArgs)parameter);
}
#endregion
}