La manipulation de la fenêtre de l'événement de clôture avec WPF / MVVM Light Toolkit
J'aimerais poignée de la "Clôture" de l'événement (lorsqu'un utilisateur clique sur la partie supérieure droite du bouton "X") de ma fenêtre afin d'afficher un message de confirmation ou/et d'annuler la fermeture.
Je sais comment le faire dans le code-behind : abonnez-vous à la "Clôture" de l'événement de la fenêtre, puis utiliser la fonction "CancelEventArgs.Annuler" de la propriété.
Mais je suis en utilisant MVVM donc je ne suis pas sûr que c'est la bonne approche.
Je pense que la bonne approche serait de lier l'événement de Clôture à une Commande dans mon ViewModel.
J'ai essayé ça :
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding CloseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Avec un associé RelayCommand dans mon ViewModel mais il ne fonctionne pas (la commande du code n'est pas exécuté).
- Également intéressé à la belle réponse à la réponse à cette question.
- J'ai téléchargé le code de codeplex et de débogage, il a révélé: "Impossible de convertir l'objet de type 'System.ComponentModel.CancelEventArgs' de type 'System.De Windows.RoutedEventArgs'." Il fonctionne très bien si vous ne pas vous voulez le CancelEventArgs mais cela ne veut pas répondre à votre question...
- Je devine que votre code ne fonctionne pas parce que le contrôle que vous avez attaché votre déclencheur n'est pas un événement de Clôture. Vos données de contexte n'est pas une fenêtre...C'est probablement un modèle de données avec une grille ou quelque chose, qui n'a pas d'événement de Clôture. Donc dbkk la réponse est la meilleure réponse dans ce cas. Cependant, je préfère l'Interaction/EventTrigger approche lorsque l'événement est disponible.
- Le code fonctionne correctement sur un événement Chargé, par exemple.
Vous devez vous connecter pour publier un commentaire.
Je voudrais simplement associer le gestionnaire dans le constructeur de la Vue:
Puis ajouter le gestionnaire de la
ViewModel
:Dans ce cas, vous gagnez exactement rien, à l'exception de la complexité à l'aide d'un modèle plus élaboré avec plus d'indirection (5 lignes supplémentaires de
XML
plus modèle de commande).Le "zéro code-behind" mantra n'est pas le but en soi, le point est à découpler le ViewModel de la Vue. Même lorsque l'événement est lié dans le code-behind de la Vue, les
ViewModel
ne dépend pas de la Vue et de la fermeture de la logique peut être de l'unité testée.Ce code fonctionne très bien:
ViewModel.cs:
et en XAML:
en supposant que
xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL5"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
i
dans<i:Interaction.Triggers>
et comment l'obtenir.xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
EventToCommand
est référencé ici? Une réponse doit être complète, ou à tout le moins demander aux utilisateurs comment trouver les bits. Utilisez-vous MVVM Light, de la Colle, de Mélange ou de l'un des autres implémentations? Qu'est-ce que lecommand
espace de noms? Cette réponse est à moitié terminé.command
espace de noms est en faitxmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL5"
Cette option est encore plus facile, et peut-être est approprié pour vous. Dans votre Modèle de Vue du constructeur, vous pouvez vous abonner à la Fenêtre Principale de l'événement de clôture comme ceci:
Le meilleur de tous.
Ici est une réponse selon le MVVM-modèle si vous ne voulez pas savoir à propos de la Fenêtre (ou l'un de ses événements) dans le ViewModel.
Dans le ViewModel ajouter l'interface et la mise en œuvre
Dans la Fenêtre-je ajouter de la Clôture de la manifestation. Ce code-behind de ne pas briser le pattern MVVM. Le point de Vue de connaître le viewmodel!
Geez, semble, comme beaucoup de code passe ici pour cela. Stas ci-dessus a eu la bonne approche pour un minimum d'effort. Voici mon adaptation (à l'aide de MVVMLight mais doit être reconnaissable)... Oh, et le PassEventArgsToCommand="True" est certainement nécessaires comme indiqué ci-dessus.
(crédit à Laurent Bugnion http://blog.galasoft.ch/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx)
Dans le modèle de vue:
dans le ShutdownService
RequestShutdown ressemble à quelque chose comme ce qui suit, mais basicallyRequestShutdown ou que ce soit, il est nommé décide de l'arrêt de l'application ou non (ce qui va gaiement fermer la fenêtre quand même):
Le demandeur doit utiliser STAS réponse, mais pour les lecteurs qui utilisent prisme et pas de galasoft/mvvmlight, ils peuvent vouloir essayer ce que j'ai utilisé:
Dans la définition en haut de la fenêtre ou usercontrol, etc définir l'espace de noms:
Et juste en dessous de cette définition:
Propriété dans le viewmodel:
Joindre delegatecommand dans votre viewmodel constructeur:
Enfin, votre code que vous voulez atteindre, à proximité de contrôle/fenêtre/quoi que ce soit:
i
!Je serais tenté d'utiliser un gestionnaire d'événements au sein de votre Application.xaml.cs fichier qui va vous permettre de décider de fermer l'application ou pas.
Par exemple, vous pourriez alors avoir quelque chose comme le code suivant dans votre Application.xaml.cs fichier:
Puis à l'intérieur de votre MainWindowViewModel code que vous pourriez avoir ce qui suit:
Fondamentalement, la fenêtre d'événement ne peut pas être attribué à MVVM. En général, le bouton de fermeture d'afficher une boîte de Dialogue pour demander à l'utilisateur d'enregistrer : oui/non/annuler", et cela peut ne pas être atteint par le MVVM.
Vous pouvez conserver le OnClosing gestionnaire d'événements, où vous appelez le Modèle.De près.CanExecute() et mettre le résultat booléen dans le cas de la propriété.
Ainsi, après la CanExecute() l'appel si la valeur est true, OU dans le OnClosed cas, appeler le Modèle.De près.Execute()
Je n'ai pas fait beaucoup de tests, mais il semble fonctionner. Voici ce que j'ai trouvé:
Nous utilisons AttachedCommandBehavior pour cela. Vous pouvez joindre tout cas à une commande sur votre façon de voir modèle en évitant de tout le code derrière.
Nous l'utilisons tout au long de notre solution et ont presque zéro code derrière
http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/
Utilisant MVVM Light Toolkit:
En supposant qu'il existe une Sortie de commande dans le modèle de vue:
Ce qui est reçu dans la vue:
D'autre part, je m'occupe de
Closing
événement dansMainWindow
, à l'aide de l'exemple de ViewModel:CancelBeforeClose
vérifie l'état actuel de la vue modèle et renvoie true si la fermeture doit être arrêté.Espère que cela aide quelqu'un.