2

私のアプリケーション レイヤーは、DialogPresenters を使用して、さまざまなダイアログ (モーダル、スプラッシュ スクリーンなど) にいくつかの ViewModel を表示します。

    public DataImportDialogPresenter(DataImportViewModel viewModel, IDialogView shellView, IDialogView owner)
        : base(viewModel, shellView, owner)
    {
        //Base sets the view data context etc.
        //Monitor CancelCommand and close the dialog
        viewModel.CancelCommand = new DelegateCommand(() => Terminate());
    }

このセットアップは非常にうまく機能しますが、ViewModel が CancelCommand で何かを行う必要があると判断した場合 (これは完全に合理的です)、プレゼンターの Terminate() への呼び出しを置き換えるか、その逆を行います。

私がやりたいことは次のとおりです。

viewModel.CancelCommand += new DelegateCommand(() => Terminate());

イベント ハンドラーをアタッチするのと同じ精神で。

  1. これは C#.NET 3.5 で可能ですか?
  2. どうすればそれを達成できますか?
  3. これは悪い MVVM プラクティスですか?

ありがとう

D

4

1 に答える 1

2

ビューモデルICommandの元の部分をラップする、インターフェイスの別の実装を使用できます。CancelCommand

public class WrapperDelegateCommand : ICommand
{
    private Action<object> _action;
    private ICommand _originalCommand;

    public WrapperDelegateCommand(Action<object> action, ICommand original)
    {
        _action = action;
        _originalCommand = original;
    }

    public bool CanExecute(object param)
    {
        if (originalCommand != null)
            return _originalCommand.CanExecute(param);
        return true;
    }

    public void Execute(object param)
    {
        if (_originalCommand != null)
            _originalCommand.Execute(param);
        _action(param);
    }

    public ICommand OriginalCommand { get { return _originalCommand; } }
}

次に、このコマンドをViewModelのコマンドに割り当てることができます。

viewModel.CancelCommand = new WrapperDelegateCommand(() => Terminate(), viewModel.CancelCommand);

そして、おそらくメソッドで元のコマンドを復元する必要がありますTerminate

viewModel.CancelCommand = (viewModel.CancelCommand as WrapperDelegateCommand).OriginalCommand;
于 2010-02-14T14:41:03.547 に答える