0

ビュー モデルで CanExecute の再評価を強制できることはわかっていますが、これにはビュー モデルが関連するすべてのデータ変更イベントに登録する必要があり、常に実行できるとは限りません。

コマンドはコンテキスト メニューでのみ使用され、コンテキスト メニューが開いている間は CanExecute に影響するデータを変更できないため、コンテキスト メニューが開いているときにだけ CanExecute を再評価すれば十分です。

これを行うには、コンテキスト メニューを開くイベントをフックし、ビュー モデルを呼び出して、コンテキスト メニューが使用する各 ICommand で RaiseCanExecuteChanged を呼び出すことができますが、これは面倒であり、MVVM に反します。これを達成するためのより簡単な方法があるかどうか疑問に思っていますか?

4

1 に答える 1

3

はいあります。この 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
}
于 2013-08-14T05:58:10.180 に答える