2010-12-02 23 views
0

Cela semble être une question stupide, mais j'ai regardé à travers les docs pour prisme et cherché sur internet et ne peut pas trouver un exemple ... Voici l'affaire.Peut exécuter la question en utilisant des commandes de délégué dans le prisme

J'utilise un DelegateCommand dans Prism, il fonctionne correctement, sauf lorsque j'attribue un délégué à l'exécution de can à la méthode CanExecute. dans un autre modèle de vue, j'ai un événement qui prend un bool que je publie aussi et je peux voir que l'événement se déclenche et que le bool est passé à mon modèle de vue avec la commande dedans pas de problème mais c'est ce que je Ne comprends pas ... Comment l'exécution peut-elle savoir que l'état a changé? Voici un code pour l'exemple.

des modèles de vue Ctor

eventAggregator.GetEvent<NavigationEnabledEvent>().Subscribe(OnNavigationEnabledChange, ThreadOption.UIThread); 

NavigateCommand = new DelegateCommand(OnNavigate,() => nextButtonEnabled); 

maintenant - ici est l'événement OnNavigationEnableChange. Comme - il me manque totalement quelque chose ici - comment la commande sait-elle que nextButtonEnabled n'est pas vrai?

Si quelqu'un pouvait me diriger vers un exemple de travail qui serait génial.

OK - merci!

+0

un peu confus sur ce que vous demandez ... vous vous demandez comment il sait quand appeler à nouveau CanExecute pour actualiser la capacité de la commande à exécuter? L'enregistrement de votre événement via l'EventAggregator Je pense qu'il est en train de brouiller les pistes ... peut-être un exemple de code plus concis car votre gestionnaire d'événements est séparé du gestionnaire de commandes. –

+0

Oui, vous avez raison avec votre première question ... Comment sait-il rafraîchir la capacité des commandes à exécuter en appelant CanExecute? Je ne l'ai pas dit aussi bien. Merci de votre aide! – Kenn

Répondre

0

C'est pourquoi je n'utilise pas l'implémentation de DelegateCommand dans Prism. J'ai toujours détesté l'approche basée sur les rappels pour activer/désactiver les commandes. C'est tout à fait inutile, et pour autant que je sache, son seul «avantage» (et plutôt douteux) est qu'il est cohérent avec la façon dont l'exécution elle-même est gérée. Mais cela m'a toujours semblé inutile car l'exécution et l'activation/désactivation sont clairement très différentes: un bouton sait quand il veut exécuter une commande mais ne sait pas quand l'état de la commande a pu changer.

Je finis toujours par écrire quelque chose comme ceci:

public class RelayCommand : ICommand 
{ 
    private bool _isEnabled; 
    private Action _onExecute; 

    public RelayCommand(Action executeHandler) 
    { 
     _isEnabled = true; 
     _onExecute = executeHandler; 
    } 

    public bool IsEnabled 
    { 
     get { return _isEnabled; } 
     set 
     { 
      _isEnabled = value; 
      if (CanExecuteChanged != null) 
      { 
       CanExecuteChanged(this, EventArgs.Empty); 
      } 
     } 
    } 


    public bool CanExecute(object parameter) 
    { 
     return _isEnabled; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     _onExecute(); 
    } 
} 

(Si nécessaire, vous pouvez modifier cette option pour utiliser des références faibles pour exécuter des gestionnaires d'événements de changement, comme Prism fait.)

Mais pour répondre votre question: comment l'approche de rappel est-elle censée fonctionner? Le DelegateCommand de Prism propose une méthode RaiseCanExecuteChanged que vous pouvez invoquer pour lui demander de déclencher l'événement qui provoquera l'invocation par les invocateurs de commandes de votre commande CanExecute. Étant donné que vous devez indiquer le DelegateCommand chaque fois que votre état activé change, je ne vois aucun avantage significatif d'une approche basée sur les rappels. (Parfois, vous voyez un modèle de diffusion - l'arrangement de sorte que n'importe quel changement de statut notifie tous les invocateurs de commande! Dans ce cas, un rappel est utile car cela signifie que cela n'a pas d'importance si vous ne savez pas ce qui a réellement changé. mais requerying chaque commande semble désagréable pour moi)

0

répondre à votre question comment la commande sait qu'il est maintenant activé.

NavigateCommand = new DelegateCommand(OnNavigate,() => nextButtonEnabled); 

Cette surcharge du constructeur DelegateCommand prend 2 paramètres: le premier est l'action de la commande et la seconde est le délégué CanExecute qui retourne bool. dans votre exemple votre action CanExecute retourne toujours nextButtonEnabled

eventAggregator.GetEvent<NavigationEnabledEvent>().Subscribe(OnNavigationEnabledChange, ThreadOption.UIThread); 

déclenche OnNavigationEnabledChange qui change nextButtonEnabled voici comment cela fonctionne ...