Je voudrais gérer l' Closing
événement (lorsqu'un utilisateur clique sur le bouton 'X' en haut à droite) de ma fenêtre afin d'afficher éventuellement un message de confirmation ou / et d'annuler la fermeture.
Je sais comment faire cela dans le code-behind: abonnez-vous à l' Closing
événement de la fenêtre puis utilisez la CancelEventArgs.Cancel
propriété.
Mais j'utilise MVVM donc je ne suis pas sûr que ce soit la bonne approche.
Je pense que la bonne approche serait de lier l' Closing
événement à un Command
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 cela ne fonctionne pas (le code de la commande n'est pas exécuté).
Réponses:
J'associerais simplement le gestionnaire dans le constructeur View:
Ajoutez ensuite le gestionnaire au
ViewModel
:Dans ce cas, vous ne gagnez exactement rien sauf la complexité en utilisant un modèle plus élaboré avec plus d'indirection (5 lignes supplémentaires de XAML plus
Command
modèle).Le mantra «zéro code derrière» n'est pas le but en soi, il s'agit de découpler ViewModel de la vue . Même lorsque l'événement est lié dans le code-behind de la vue, le
ViewModel
ne dépend pas de la vue et la logique de fermeture peut être testée unitaire .la source
Ce code fonctionne très bien:
ViewModel.cs:
et en XAML:
en admettant que:
DataContext
des conteneurs principaux.xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL5"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
la source
i
dans<i:Interaction.Triggers>
et comment l'obtenir.xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Cette option est encore plus simple et vous convient peut-être. Dans votre constructeur de modèle de vue, vous pouvez vous abonner à l'événement de fermeture de la fenêtre principale comme ceci:
Bonne chance.
la source
Voici une réponse selon le modèle MVVM si vous ne voulez pas connaître la fenêtre (ou l'un de ses événements) dans le ViewModel.
Dans le ViewModel, ajoutez l'interface et l'implémentation
Dans la fenêtre, j'ajoute l'événement de clôture. Ce code derrière ne rompt pas le modèle MVVM. La vue peut connaître le modèle de vue!
la source
IClosing
interface, pas seulement implémenter laOnClosing
méthode. Sinon, leDataContext as IClosing
casting échouera et reviendranull
Décidément, il semble que beaucoup de code se passe ici pour cela. Stas ci-dessus avait la bonne approche pour un effort minimal. Voici mon adaptation (en utilisant MVVMLight mais devrait être reconnaissable) ... Oh et le PassEventArgsToCommand = "True" est définitivement nécessaire 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 à ce qui suit, mais en gros, RequestShutdown ou quel que soit son nom décide d'arrêter l'application ou non (ce qui fermera joyeusement la fenêtre de toute façon):
la source
Le demandeur doit utiliser la réponse STAS, mais pour les lecteurs qui utilisent prism et pas de galasoft / mvvmlight, ils voudront peut-être essayer ce que j'ai utilisé:
Dans la définition en haut de window ou usercontrol, etc. définissez l'espace de noms:
Et juste en dessous de cette définition:
Propriété dans votre modèle de vue:
Attachez delegatecommand dans votre constructeur viewmodel:
Enfin, votre code que vous souhaitez atteindre à la fermeture du champ / fenêtre / peu importe:
la source
Je serais tenté d'utiliser un gestionnaire d'événements dans votre fichier App.xaml.cs qui vous permettra de décider de fermer ou non l'application.
Par exemple, vous pourriez avoir quelque chose comme le code suivant dans votre fichier App.xaml.cs:
Ensuite, dans votre code MainWindowViewModel, vous pouvez avoir les éléments suivants:
la source
Fondamentalement, l'événement de fenêtre ne peut pas être affecté à MVVM. En général, le bouton Fermer affiche une boîte de dialogue pour demander à l'utilisateur "enregistrer: oui / non / annuler", et cela peut ne pas être réalisé par le MVVM.
Vous pouvez conserver le gestionnaire d'événements OnClosing, où vous appelez Model.Close.CanExecute () et définissez le résultat booléen dans la propriété event. Donc, après l'appel CanExecute () si true, OU dans l'événement OnClosed, appelez Model.Close.Execute ()
la source
Je n'ai pas fait beaucoup de tests avec cela, mais cela semble fonctionner. Voici ce que j'ai trouvé:
la source
Nous utilisons AttachedCommandBehavior pour cela. Vous pouvez attacher n'importe quel événement à une commande sur votre modèle de vue en évitant tout code derrière.
Nous l'utilisons dans toute notre solution et n'avons pratiquement aucun code derrière
http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/
la source
Utilisation de MVVM Light Toolkit:
En supposant qu'il existe une commande Quitter dans le modèle de vue:
Ceci est reçu dans la vue:
D'autre part, je gère les
Closing
événements dansMainWindow
, en utilisant l'instance de ViewModel:CancelBeforeClose
vérifie l'état actuel du modèle de vue et renvoie true si la fermeture doit être arrêtée.J'espère que ça aide quelqu'un.
la source
la source