如何重新查询单个RoutedCommand的'CanExecute'?

4
我需要刷新一个或多个(尽管不是全部)RoutedCommand对象的CanExecute状态。
我知道可以使用以下方法更新所有命令
CommandManager.InvalidateRequerySuggested();

由于此更新比必要的命令多,因此在我的应用程序中调用此函数有时会导致性能问题。

我最初的希望是手动调用CanExecute()也会在状态更改时触发事件,但事实并非如此。

当查看参考源代码时,CanExecuteChanged似乎无法访问,以提供某种扩展到RoutedCommand类的派生类,以允许手动引发事件。

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

有什么想法可以实现这样的机制吗?我知道DelegateCommand,但我需要一个路由命令,所以我不认为这个类能帮助我。
1个回答

3

您可以创建自己的自定义RoutedCommand,重新实现ICommand并自行注册其他事件。请注意,在这里使用new应该是安全的,因为WPF将使用ICommand引用调用CanExecuteChanged

public class MyRoutedCommand : RoutedCommand, ICommand
{
    private event EventHandler _canExecuteChanged;

    public void RaiseCanExecuteChanged()
    {
        var handler = _canExecuteChanged;
        if (handler != null) handler(this, EventArgs.Empty);
    }

    public new event EventHandler CanExecuteChanged
    {
        add
        {
            _canExecuteChanged += value;
            base.CanExecuteChanged += value;
        }
        remove
        {
            _canExecuteChanged -= value;
            base.CanExecuteChanged -= value;
        }
    }
}

请注意,尽管WPF将使用WeakEventManager注册此事件,但其他开发人员可能不会这样做。 由于路由命令通常定义为静态字段,因此这可能导致潜在的内存泄漏。 您可以实现弱事件管理器以防止此问题。


嘿,不错。我自己尝试了几乎相同的代码,但只有在将ICommand添加到接口列表中时才有效,这一点我没有考虑到。谢谢。 - floele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接