Ich würde gerne damit umgehen Closing
Ereignis (wenn ein Benutzer auf die Schaltfläche "X" oben rechts klickt) meines Fensters behandeln, um eventuell eine Bestätigungsmeldung anzuzeigen oder / und das Schließen abzubrechen.
Ich weiß, wie das im Code-Behind geht: Abonnieren Sie das Closing
Ereignis des Fensters und verwenden Sie dann die CancelEventArgs.Cancel
Eigenschaft.
Aber ich benutze MVVM und bin mir nicht sicher, ob es der gute Ansatz ist.
Ich denke, der gute Ansatz wäre, das Closing
Ereignis an ein Command
in meinem ViewModel zu binden .
Ich habe das versucht:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding CloseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Mit einem RelayCommand
in meinem ViewModel verknüpften, aber es funktioniert nicht (der Code des Befehls wird nicht ausgeführt).
Antworten:
Ich würde den Handler einfach im View-Konstruktor zuordnen:
Fügen Sie dann den Handler zu
ViewModel
:In diesem Fall erhalten Sie genau etwas anderes als Komplexität, wenn Sie ein ausgefeilteres Muster mit mehr Indirektion verwenden (5 zusätzliche Zeilen XAML plus
Command
Muster).Das "Zero Code-Behind" -Mantra ist nicht das eigentliche Ziel, es geht darum, ViewModel von der Ansicht zu entkoppeln . Selbst wenn das Ereignis im Code-Behind der Ansicht gebunden ist,
ViewModel
hängt dies nicht von der Ansicht ab und die Abschlusslogik kann Unit-getestet werden .quelle
Dieser Code funktioniert einwandfrei:
ViewModel.cs:
und in XAML:
vorausgesetzt, dass:
DataContext
der Hauptcontainer zugeordnet .xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL5"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
quelle
i
in ,<i:Interaction.Triggers>
und wie es zu bekommen.xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Diese Option ist noch einfacher und möglicherweise für Sie geeignet. In Ihrem View Model-Konstruktor können Sie das Abschlussereignis des Hauptfensters wie folgt abonnieren:
Alles Gute.
quelle
Hier ist eine Antwort gemäß dem MVVM-Muster, wenn Sie nichts über das Fenster (oder eines seiner Ereignisse) im ViewModel wissen möchten.
Fügen Sie im ViewModel die Schnittstelle und die Implementierung hinzu
Im Fenster füge ich das Closing-Ereignis hinzu. Dieser Code dahinter bricht das MVVM-Muster nicht. Die Ansicht kann über das Ansichtsmodell Bescheid wissen!
quelle
IClosing
Schnittstelle implementieren , nicht nur dieOnClosing
Methode. Andernfalls wird dieDataContext as IClosing
Besetzung scheitern und zurückkehrennull
Meine Güte, hier scheint eine Menge Code dafür zu laufen. Stas oben hatte den richtigen Ansatz für minimalen Aufwand. Hier ist meine Anpassung (mit MVVMLight, sollte aber erkennbar sein) ... Oh und das PassEventArgsToCommand = "True" ist definitiv benötigt, wie oben angegeben.
(Dank an Laurent Bugnion http://blog.galasoft.ch/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx )
Im Ansichtsmodell:
im ShutdownService
RequestShutdown sieht ungefähr so aus, aber im Grunde entscheidet RequestShutdown oder wie auch immer es heißt, ob die Anwendung heruntergefahren werden soll oder nicht (wodurch das Fenster ohnehin fröhlich geschlossen wird):
quelle
Der Fragesteller sollte die STAS-Antwort verwenden, aber für Leser, die Prisma und kein galasoft / mvvmlight verwenden, möchten sie möglicherweise versuchen, was ich verwendet habe:
Definieren Sie in der Definition oben für Fenster- oder Benutzersteuerung usw. den Namespace:
Und genau unter dieser Definition:
Eigenschaft in Ihrem Ansichtsmodell:
Fügen Sie delegatecommand in Ihren viewmodel-Konstruktor ein:
Schließlich Ihren Code, den Sie beim Schließen des Steuerelements / Fensters / was auch immer erreichen möchten:
quelle
Ich wäre versucht, einen Ereignishandler in Ihrer App.xaml.cs-Datei zu verwenden, mit dem Sie entscheiden können, ob Sie die Anwendung schließen möchten oder nicht.
Zum Beispiel könnten Sie dann so etwas wie den folgenden Code in Ihrer App.xaml.cs-Datei haben:
Dann könnten Sie in Ihrem MainWindowViewModel-Code Folgendes haben:
quelle
Grundsätzlich kann das Fensterereignis MVVM nicht zugewiesen werden. Im Allgemeinen wird auf der Schaltfläche Schließen ein Dialogfeld angezeigt, in dem der Benutzer aufgefordert wird, "Speichern: Ja / Nein / Abbrechen" zu senden. Dies wird möglicherweise von der MVVM nicht erreicht.
Sie können den OnClosing-Ereignishandler beibehalten, in dem Sie Model.Close.CanExecute () aufrufen und das boolesche Ergebnis in der Ereigniseigenschaft festlegen. Rufen Sie nach dem Aufruf von CanExecute (), falls true, ODER im Ereignis OnClosed, Model.Close.Execute () auf.
quelle
Ich habe nicht viel damit getestet, aber es scheint zu funktionieren. Folgendes habe ich mir ausgedacht:
quelle
Wir verwenden hierfür AttachedCommandBehavior. Sie können ein Ereignis an einen Befehl in Ihrem Ansichtsmodell anhängen, ohne dass Code dahinter steckt.
Wir verwenden es in unserer gesamten Lösung und haben fast keinen Code dahinter
http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/
quelle
Verwenden des MVVM Light Toolkit:
Angenommen, das Ansichtsmodell enthält einen Befehl Beenden :
Dies wird in der Ansicht empfangen:
Auf der anderen Seite behandle ich
Closing
Ereignisse inMainWindow
mithilfe der Instanz von ViewModel:CancelBeforeClose
Überprüft den aktuellen Status des Ansichtsmodells und gibt true zurück, wenn das Schließen gestoppt werden soll.Hoffe es hilft jemandem.
quelle
quelle