2010-02-14 6 views
2

Ma couche Application utilise DialogPresenters pour afficher certains ViewModels dans divers dialogues (modal, splash screen, etc.).Gestionnaires de commandes multiples MVVM

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()); 
    } 

Cette configuration fonctionne très bien à l'exception du fait que si mon ViewModel décide qu'il a besoin de faire quelque chose sur le CancelCommand (ce qui est tout à fait raisonnable), il remplacera l'appel du présentateur à Terminate() ou vice-versa .

Ce que je voudrais faire est la suivante:

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

Dans le même esprit que la fixation des gestionnaires d'événements.

  1. Est-ce possible en C# .NET 3.5?
  2. Comment l'obtenir?
  3. Est-ce une mauvaise pratique MVVM?

Merci

D

Répondre

2

Vous pouvez utiliser une autre implémentation de l'interface ICommand, qui enveloppait la CancelCommand originale du ViewModel:

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; } } 
} 

Vous pouvez ensuite attribuer cette commande à la commande ViewModel:

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

Et vous devez probablement restaurer la commande d'origine dans la méthode Terminate:

viewModel.CancelCommand = (viewModel.CancelCommand as WrapperDelegateCommand).OriginalCommand; 
+0

qui fonctionnera dans mon cas en cours d'utilisation. Ma seule préoccupation est que le viewmodel pourrait écraser la commande sans le savoir. – djskinner

+0

Je vois votre point ... J'initialise habituellement la commande paresseusement dans le getter. Si vous faites cela, et ne changez jamais la commande par la suite, cela devrait fonctionner –

Questions connexes