CanExecute Logique pour DelegateCommand
Mise à jour: L'accent est devenu MVVM à la place de la question si je suis à jour.
Je vais avoir un problème avec CanExecute
pour DelegateCommand
. Elle n'est pas mise à jour avant que j'appelle RaiseCanExecuteChanged
, est-ce le comportement souhaité?
J'ai téléchargé un simple exemple de projet de reproduire ce problème ici : http://dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
Le problème est le suivant, j'ai deux Buttons
comme ça. L'une est la Liaison Command
à un RelayCommand
la mise en œuvre et l'autre est contraignant pour le Prisme de la mise en œuvre de DelegateCommand
<Button Command="{Binding DelegateSaveCommand}"/>
<Button Command="{Binding RelaySaveCommand}"/>
Le ViewModel ICommands
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate);
RelaySaveCommand = new RelayCommand(param => Save(), param => CanSaveRelay);
et la CanExecute
méthode/prédicat
public bool CanSaveDelegate()
{
return HasChanges;
}
public bool CanSaveRelay
{
get { return HasChanges; }
}
Les deux sont à l'aide de la propriété HasChanges
. Lorsque HasChanges
est mis à jour, seule la CanSaveRelay
mises à jour. Est-ce la façon dont il est censé être?
RelayCommand
au lieu de le PRISME de l' DelegateCommand
. J'ai vu un article quelque part sur la recompilation du Prisme de la bibliothèque, pour ajouter l'événement CanExecuteChanged, mais je ne peux pas le trouver maintenant (Pense que c'était PRISME 2 de toute façon)J'en ai pris 2 différentes suppositions quant à ce que le problème pourrait être, mais sans voir le code, il m'est impossible de savoir exactement quelle est la cause.
Vous pourriez faire la même chose que Meleak, donc ma solution de référence pour l'explication de la pourquoi et comment le résoudre.
Aussi, si le problème est que votre Modèle est en train de faire la modification de la propriété et la sensibilisation de la propertychanged des événements à l'époque qui est en train de changer la propriété de l'État?
Le PropertyChanged est soulevée par l'entité qui est généré à partir de la Base de données. Je suis en train de lire votre réponse maintenant
OriginalL'auteur Fredrik Hedblad | 2011-09-08
Vous devez vous connecter pour publier un commentaire.
Comme elle l'a déjà été mentionné, c'est un comportement intentionnel de
DelagateCommand
, pas un bug.DelegateCommand
ne soulève pasCanExecuteChanged
événement automatiquement, vous devez faire de cet événement manuellement en appelantRaiseCanExecuteChanged
le cas échéant. Alors queRelayCommand
relais surCommandManager.RequerySuggested
événement. Cet événement est déclenché à chaque fois que l'utilisateur clique ou appuie sur un bouton.Pour les situations où il n'est pas très pratique ou il n'y a pas d'endroit approprié pour appeler
RaiseCanExecuteChanged
(comme dans votre scénario, vous devez vous abonner àPropertyChanged
événement sur le modèle, etc) j'ai créé le wrapper simple, qui garantit que leCanExecute
méthode de la enveloppé commande est exécutée automatiquement surCommandManager.RequerySuggested
événement:Vous pouvez l'utiliser comme ceci:
CommandManager.RequerySuggested
, qui est déclenché uniquement lorsque l'utilisateur clique ou appuie sur une touche (comme mentionné dans la réponse) . Si l'utilisateur ne clique pas n'importe où, la commande restera inactif, ce qui pourrait être source de confusion.Il y a une situation où je veux utiliser votre classe Wrapper ainsi que DelegateCommand. Parce qu'il est nécessaire de RaiseCanExecuteCommand automatiquement que manuellement. Après ceci est fait automatiquement de vous dire quel est le besoin de l'appeler manuellement. Il est nécessaire d'appeler manuellement, car je suis l'évolution focus sur un bouton qui est désactivé. Donc, je veux activer le bouton en appelant RaiseCanExecuteCommand manally. Suite dans le prochain commentaire....
En passant, j'ai essayé de assing nouveau AutoCanExecuteCommandWrapper(nouveau DelegateCommand(Enregistrer, CanSaveDelegate)) à un DelegateCommand mais j'obtiens une erreur qui Ne peut pas Convertir le type de AutoCanExecuteCommand à DelegateCommand.
OriginalL'auteur Pavlo Glazkov
Il y a un bug dans le DelegateCommand fournis par le Prisme qui ne soulève pas la CanExecute événement. J'ai battu ma tête contre le mur pour une journée jusqu'à ce que je me suis plongé dans le
DelegateCommand
classe fournie par le Prisme du cadre. Je n'ai pas le code avec moi, mais je peux poster ma résolution en bits.L'alternative est d'utiliser l'un de l'autre RelayCommand cadres.
Modifier
Plutôt que de reposter le code, il y a d'autres DONC des questions qui fournissent des résolutions:
Et Kent B. a un bon article: MVVM Infrastructure: DelegateCommand
RelayCommand
mise en œuvre trouvés dans Josh Smiths MVVM l'article (et l'ont été pendant une longue période) et j'en suis très satisfait. Juste pensé que je devrais utiliser leDelegateCommand
fournis par le Prisme depuis que je suis à l'aide de Prism 4 maintenant.. hâte de voir votre correctif 🙂Non, il n'est pas un bug. Le choix entre la voie de liaison (du prisme de Clic.De commande ou de commandes WPF) est la raison pour laquelle vous devez appeler RaiseCanExecuteChanged. Il a été fait pour donner le programmeur plus de contrôle sur la date de l'exécution d'un CanExecute délégué. Comme je l'ai dit précédemment, si vous voulez que votre contrôle à TOUJOURS requête de la méthode CanExecute, puis utilisez le
Command
de propriété sur votre contrôle. Si vous voulez choisir lors de la commande doit interroger la méthode CanExecute, puis utilisez leClick.Command
propriété attachée sur votre contrôle.Je me souviens que j'ai rencontré le même comportement, indépendamment de l'utilisation de la
Command
de la propriété ou de la propriété attachée. Il a été un certain temps, cependant. Après nous avons mis à jour notre bibliothèque avec un "fixer" à la valeur par défautDelegateCommand
je n'ai jamais regardé en arrière.Schtroumpf: Voir ma mise à jour de question si vous avez le temps. J'ai téléchargé un exemple de projet montrant le problème. Est-ce un bug ou le comportement souhaité? Merci
Le scénario que vous décrivez dans la mise à jour de la question est exactement la même chose, j'ai battu ma tête contre le mur quand j'ai rencontré le même comportement. Kent B de l'article que j'ai posté a une mise à jour DelegateCommand (IIRC) qui résout le problème. Je vais aussi poster le code que j'ai utilisé pour résoudre le Prisme
DelegateCommand
(quelques heures au milieu d'un bouton de brassage sql).OriginalL'auteur Metro Smurf