Wie beende ich eine WPF-Anwendung programmgesteuert?

478

In den wenigen Jahren, in denen ich C # (Windows Forms) verwendet habe, habe ich nie WPF verwendet. Aber jetzt liebe ich WPF, aber ich weiß nicht, wie ich meine Anwendung beenden soll, wenn der Benutzer im Menü Datei auf den Menüpunkt Beenden klickt.

Ich habe versucht:

this.Dispose();
this.Exit();
Application.ShutDown();
Application.Exit();
Application.Dispose();

Unter vielen anderen. Nichts funktioniert.

Peter Mortensen
quelle

Antworten:

781

Um Ihre Anwendung zu beenden, können Sie anrufen

System.Windows.Application.Current.Shutdown();

Wie in der Dokumentation zur Application.ShutdownMethode beschrieben, können Sie das Herunterfahrverhalten Ihrer Anwendung auch ändern, indem Sie einen ShutdownMode angeben :

Das Herunterfahren wird von Windows Presentation Foundation (WPF) in den folgenden Situationen implizit aufgerufen:

  • Wenn ShutdownMode auf OnLastWindowClose eingestellt ist.
  • Wenn der ShutdownMode auf OnMainWindowClose eingestellt ist.
  • Wenn ein Benutzer eine Sitzung beendet und das SessionEnding-Ereignis entweder nicht behandelt oder ohne Abbruch behandelt wird.

Bitte beachten Sie auch, dass dies Application.Current.Shutdown();möglicherweise nur von dem Thread aufgerufen wird, der das ApplicationObjekt erstellt hat, dh normalerweise vom Hauptthread.

Dirk Vollmar
quelle
8
Wie ich schon sagte, ist es nicht komisch. In WPF Application ist eine statische Klasse. Application.Current ist ein Verweis auf Ihre aktuell ausgeführte Anwendung.
TimothyP
4
Meiner Meinung nach ist es etwas seltsam in dem Sinne, dass dies auf den ersten Blick nicht offensichtlich ist und gerade genug von früheren Modellen abweicht, um die Leute abzuwerfen. Es macht durchaus Sinn, dass es natürlich funktioniert.
Brian MacKay
20
Wenn Sie anrufen, wird Application.Current.Shutdown();Ihre Funktion nicht sofort zurückkehren. Sie müssen auch dafür anrufen return;.
Erwin Mayer
2
Ich habe dies verwendet, wo von einem Fenster aus ein anderes Fenster geöffnet wurde, und im window_closed-Ereignis dieses Fensters habe ich diesen Code hinzugefügt. Alle Fenster verschwinden, aber das Programm läuft immer noch über die Stelle hinaus, an der das Popup erstellt wurde.
diyoda_
7
@ TimothyP Nein Applicationist KEINE statische Klasse. Ein Application.Currentstatisches Mitglied zu haben bedeutet nicht, dass es statisch ist. Stattdessen ist es eine normale Klasse, die abgeleitet werden kann.
Earth Engine
156

Wenn Sie es wirklich zum Schließen benötigen, können Sie auch Environment.Exit () verwenden. , aber es ist überhaupt nicht anmutig (eher wie das Beenden des Prozesses).

Verwenden Sie es wie folgt:

Environment.Exit(0)
John
quelle
4
Environment.Exit()benötigt mindestens einen Parameter, einen Exit-Code. Verwenden Environment.Exit(0)Sie diese Option, wenn Sie sich keine Gedanken über den Exit-Code machen.
Gbmhunter
24
Diese Methode schloss eigentlich alles. Meine App ließ etwas laufen (das Formular wurde geschlossen, aber ein Prozess lief noch) mitApplication.Current.Shutdown();
gbmhunter
4
Environment.Exit ist definitiv der richtige Weg, um das Herunterfahren einer Anwendung sicherzustellen. Mit Application.Current.Shutdown kann die Anwendung problemlos auf unbestimmte Zeit ausgeführt werden, wenn Sie über Code verfügen, der sich selbst in den Dispatcher zurückschiebt.
Marcus Andrén
So gleich wie Application.exit (0);
Sayka
Mit Application.Current.Shutdown();meiner ClosingVeranstaltung wurde aufgerufen, als ich einfach meine App sofort herunterfahren wollte. Also Environment.Exit(0);war die bessere Wahl.
FredM
64

Wie Wuminqi sagte ,Application.Current.Shutdown(); ist es irreversibel, und ich glaube, es wird normalerweise verwendet, um das Schließen einer Anwendung zu erzwingen, beispielsweise wenn sich ein Benutzer abmeldet oder Windows herunterfährt.

Rufen this.close()Sie stattdessen in Ihrem Hauptfenster auf. Dies entspricht dem Drücken von Alt+ F4oder der Schaltfläche [x] zum Schließen im Fenster. Dadurch werden alle anderen Fenster geschlossen und aufgerufen Application.Current.Shutdown();, solange die Schließaktion nicht abgebrochen wurde. Weitere Informationen finden Sie in der MSDN-Dokumentation zum Schließen eines Fensters .

Da dies this.close()stornierbar ist, können Sie im Abschlussereignishandler einen Bestätigungsdialog zum Speichern von Änderungen einfügen. Erstellen Sie einfach einen Event-Handler für <Window Closing="...">und ändern Sie ihn e.Cancelentsprechend. ( Weitere Informationen hierzu finden Sie in der MSDN-Dokumentation .)

Allen Pestaluky
quelle
2
+1 Ich habe mich für diese entschieden, zumal ich geöffnete Dateien speichern muss, bevor ich die Anwendung tatsächlich beende.
AgentKnopf
2
Eine wichtige Sache, die hier zu beachten ist, ist die Tatsache, dass Allen auf eine sehr wichtige Tatsache hingewiesen hat: Alle anderen eigenen Fenster werden geschlossen. Sie müssen sicherstellen, dass Sie das Eigentum erklären. Wenn Sie ein Fenster haben, das ausgeführt wird, und dann ein anderes Fenster öffnen, es aber noch nicht anzeigen, erzwingt das ausgeblendete Fenster nach dem Schließen des aktiven Fensters, dass die Anwendung weiter ausgeführt wird. Sie haben möglicherweise einen Speicherverlust, es sei denn, Sie schließen dieses Fenster auf andere Weise (Task-Manager usw.). Ich habe das getestet.
BK
35

Verwenden Sie nach Bedarf eine der folgenden Methoden:

1.

 App.Current.Shutdown();
OR
 Application.Current.Shutdown();

2.

 App.Current.MainWindow.Close();
OR
 Application.Current.MainWindow.Close();

Vor allem Methoden werden closing eventvon Windowclass aufgerufen und die Ausführung kann irgendwann aufhören (weil Anwendungen normalerweise Dialoge wie "Sind Sie sicher?" Oder " Möchten Sie Daten vor dem Schließen speichern?" Setzen, bevor ein Fenster vollständig geschlossen wird).

3. Wenn Sie die Anwendung jedoch ohne Vorwarnung sofort beenden möchten . Verwenden Sie unten

   Environment.Exit(0);
Kylo Ren
quelle
18

So mache ich meine:

// Any control that causes the Window.Closing even to trigger.
private void MenuItemExit_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

// Method to handle the Window.Closing event.
private void Window_Closing(object sender, CancelEventArgs e)
{
    var response = MessageBox.Show("Do you really want to exit?", "Exiting...",
                                   MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
    if (response == MessageBoxResult.No)
    {
        e.Cancel = true;
    }
    else
    {
        Application.Current.Shutdown();
    }
}

Ich rufe nur Application.Current.ShutDown()aus dem Hauptanwendungsfenster an, alle anderen Fenster verwenden this.Close(). Behandelt in meinem Hauptfenster Window_Closing(...)die xSchaltfläche oben rechts . Wenn eine der Methoden einen Fensterschließer erfordert, wird Window_Closing(...)das Ereignis zum Herunterfahren abgerufen, wenn der Benutzer dies bestätigt.

Der Grund, den ich tatsächlich Application.Current.Shutdown()in meinem Hauptfenster verwende, ist, dass ich festgestellt habe, dass, wenn ein Designfehler gemacht wurde und ich kein übergeordnetes Element eines meiner Fenster in einer Anwendung deklariert habe, dieses Fenster geöffnet wird, ohne vorher angezeigt zu werden Bis zum letzten aktiven Schließen des Fensters bleibt im Hintergrund ein verstecktes Fenster. Die Anwendung wird nicht heruntergefahren. Die einzige Möglichkeit, einen vollständigen Speicherverlust zu verhindern, besteht darin, dass ich in den Task-Manager gehe , um die Anwendung herunterzufahren. Application.Current.Shutdown()schützt mich vor unbeabsichtigten Designfehlern.

Das ist aus meiner persönlichen Erfahrung. Verwenden Sie am Ende das Beste für Ihr Szenario. Dies ist nur eine weitere Information.

BK
quelle
16

Es sollte keine Application.ShutDown();oder .Exit()Nachricht geben.

Applicationist eine statische Klasse. Es bezieht sich nicht auf die aktuelle Anwendung. Sie müssen zur aktuellen Anwendung gelangen und diese dann wie folgt herunterfahren:

Application.Current.Shutdown();
TimothyP
quelle
8

Eine andere Möglichkeit, dies zu tun:

System.Diagnostics.Process.GetCurrentProcess().Kill();

Dadurch wird das Beenden Ihrer Anwendung erzwungen. Es funktioniert immer, auch in einer Multithread-Anwendung.

Hinweis: Achten Sie nur darauf, nicht gespeicherte Daten in einem anderen Thread nicht zu verlieren.

Ali Yousefi
quelle
Dies scheint unverständlich: "In Bearbeitung funktioniert immer" . Kannst du das Reparieren? Oder zumindest hier in Kommentaren erklären, was du meinst?
Peter Mortensen
Dies ist auch teilweise unverständlich: Kümmern Sie sich nur um eine Anwendung, die Daten in Dateien eines anderen Threads gespeichert hat. Kannst du das Reparieren? Oder zumindest hier in Kommentaren erklären, was du meinst?
Peter Mortensen
Benutzen Sie den Google Übersetzer?
Peter Mortensen
Nein, das tue ich nicht. Mein Mittelwert ist, wenn die Anwendung als Multithread ausgeführt wird und Sie Process.Kill verwenden. Dies funktioniert jedoch auf andere Weise. Schließen Sie, dass Sie in Multithread-Anwendungen nicht arbeiten, wenn ein anderer Thread ausgeführt wird.
Ali Yousefi
6
private void _MenuExit_Click(object sender, RoutedEventArgs e)
{
   System.Windows.Application.Current.MainWindow.Close();
}

//Override the onClose method in the Application Main window

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    MessageBoxResult result =   MessageBox.Show("Do you really want to close", "",
                                          MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.Cancel)
    {
       e.Cancel = true;
    }
    base.OnClosing(e);
}
Ravi
quelle
Dies ist nicht die Frage, die er nur wissen möchte, wie man die wpf-Anwendung beendet.
Mehdi
6

Versuchen

App.Current.Shutdown();

Für mich

Application.Current.Shutdown(); 

hat nicht funktioniert.

Iwona Kubowicz
quelle
6

Hat nach meinem Verständnis Application.Current.Shutdown()auch seinen Nachteil.

Wenn Sie ein Bestätigungsfenster anzeigen möchten, in dem Benutzer beim Beenden bestätigen können oder nicht, Application.Current.Shutdown()ist dies irreversibel.

wuminqi
quelle
7
Ich verstehe das nicht Wir können jedoch eine Benutzerbestätigung erhalten, bevor wir anrufen Application.Current.Shutdown().
Amsakanna
2
Ich verstehe nicht, warum Sie bestätigen sollten. Zu viele Bestätigungen sind eine sehr schlechte Sache. Die Tatsache, dass sich jemand die Mühe gemacht hat, zu klicken, um das Menü Datei zu öffnen, ganz nach unten im Menü Datei zu gehen und dann auf Beenden zu klicken, ist ziemlich bestätigt, dass er die Anwendung nicht mehr verwenden möchte.
Veer: In meinem Fall wird das Bestätigungsfenster angezeigt, aber selbst wenn Sie in der Bestätigung "Abbrechen" wählen, wird die Haupt-APP beendet.
Wuminqi
7
JTS: Dies ist besser von Fall zu Fall zu gestalten. Unsere App, wenn Jobs ausgeführt werden, wird der Force-Exit Schäden verursachen, daher sollten wir sie besser im Bestätigungsdialog informieren
Wuminqi
3

Zusammenfassend gibt es einige Möglichkeiten, dies zu tun.

1) Beenden des Prozesses, der die Finalisierung, Fehlerbehandlung usw. überspringt:

Process.GetCurrentProcess().Kill();

2) Beenden der aktuellen Anwendung, was wahrscheinlich der richtige Weg ist, da die Exit-Ereignisse aufgerufen werden:

Application.Current.Shutdown();

oder

this.Shutdown();

(wenn in einer Instanz der App-Klasse geklickt)

3) Aktuelle App schließen (alle Formulare müssen früher geschlossen / ausgefüllt werden):

this.Close(); 

(wenn in einer Instanz der App-Klasse geklickt)

4) Verlassen der Umgebung, wodurch die App beendet wird:

Environment.Exit(0);

Vielleicht möchten Sie hier auch mehr über Exit-Status lesen

burgund
quelle
2

Caliburn Mikrogeschmack

public class CloseAppResult : CancelResult
{
    public override void Execute(CoroutineExecutionContext context)
    {
        Application.Current.Shutdown();
        base.Execute(context);
    }
}

public class CancelResult : Result
{
    public override void Execute(CoroutineExecutionContext context)
    {
        OnCompleted(this, new ResultCompletionEventArgs { WasCancelled = true });
    }
}
Anders
quelle
Was bedeutet "Caliburn Micro Flavoured" ?
Peter Mortensen
Wie Sie es mit Caliburn Micro
Anders
0

Wenn Sie einen anderen Thread beenden möchten, der das Anwendungsobjekt nicht erstellt hat, verwenden Sie:

System.Windows.Application.Current.Dispatcher.InvokeShutdown();
SoumyaMahunt
quelle
-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;

Alpha-LIon
quelle
2
Willkommen bei SO, Alpha-LIon! Von Nur-Code-Antworten wird hier abgeraten, da sie keinen Einblick in die Lösung des Problems geben. Bitte aktualisieren Sie Ihre Lösung mit einer Erklärung, wie Ihr Code das Problem des OP löst :)
Joel
-3

Aus xaml-Code können Sie einen vordefinierten Systembefehl aufrufen:

Command="SystemCommands.MinimizeWindowCommand"

Ich denke, das sollte der bevorzugte Weg sein ...

Markus Sommerschnee
quelle
Minimieren! = Anwendung beenden. Ich sehe keine Exit-App-Option in dieser Liste. Scheint mehr Fensterverwaltung und Fenster schließen bedeutet nicht unbedingt, App zu schließen. msdn.microsoft.com/en-us/library/…
kenny