Jak programowo wyjść z aplikacji WPF?

478

Przez kilka lat korzystałem z C # (Windows Forms), nigdy nie korzystałem z WPF. Ale teraz uwielbiam WPF, ale nie wiem, jak mam wyjść z mojej aplikacji, gdy użytkownik kliknie element menu Wyjdź z menu Plik.

Próbowałem:

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

Wśród wielu innych. Nic nie działa.

Peter Mortensen
źródło

Odpowiedzi:

781

Aby wyjść z aplikacji, możesz zadzwonić

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

Jak opisano w dokumentacji Application.Shutdownmetody, można również zmodyfikować zachowanie podczas zamykania aplikacji, określając tryb ShutdownMode :

Shutdown jest domyślnie wywoływany przez Windows Presentation Foundation (WPF) w następujących sytuacjach:

  • Gdy ShutdownMode jest ustawiony na OnLastWindowClose.
  • Gdy ShutdownMode jest ustawiony na OnMainWindowClose.
  • Gdy użytkownik zakończy sesję, a zdarzenie SessionEnding jest albo nieobsługiwane, albo obsługiwane bez anulowania.

Należy również pamiętać, że Application.Current.Shutdown();można go wywoływać tylko z wątku, który utworzył Applicationobiekt, tj. Zwykle z głównego wątku.

Dirk Vollmar
źródło
8
Jak zauważyłem, to nie jest dziwne. W WPF Application jest klasą statyczną. Application.Current to odniesienie do aktualnie uruchomionej aplikacji.
TimothyP
4
Moim zdaniem jest to trochę dziwne w tym sensie, że na pierwszy rzut oka nie jest to oczywiste i odbiega od wcześniejszych modeli na tyle, aby zrzucić ludzi. To ma sens, że oczywiście działa.
Brian MacKay
20
Jeśli zadzwonisz, Application.Current.Shutdown();fonction nie wróci natychmiast. Musisz return;również do tego zadzwonić .
Erwin Mayer,
2
Użyłem tego, gdy z jednego okna wyskoczyło inne okno, aw zdarzeniu window_closed tego okna dodałem ten kod. wszystkie okna znikają, ale program nadal działa poza miejscem, w którym jest tworzone okno podręczne.
diyoda_
7
@TimothyP No ApplicationNIE jest klasą statyczną. Posiadanie elementu Application.Currentstatycznego nie oznacza, że ​​jest on statyczny. Zamiast tego można wyprowadzić normalną klasę.
Earth Engine
156

Jeśli naprawdę potrzebujesz go zamknąć, możesz także użyć Environment.Exit () , ale wcale nie jest to taktowne (bardziej przypomina zakończenie procesu).

Użyj go w następujący sposób:

Environment.Exit(0)
Jan
źródło
4
Environment.Exit()wymaga co najmniej jednego parametru, kodu wyjścia. Użyj, Environment.Exit(0)jeśli nie martwi Cię kod wyjścia.
gbmhunter
24
Ta metoda faktycznie zamknęła wszystko. Moja aplikacja pozostawia coś uruchomionego (formularz się zamykał, ale proces wciąż działał) zApplication.Current.Shutdown();
gbmhunter
4
Environment.Exit to zdecydowanie właściwy sposób na zamknięcie aplikacji. Dzięki Application.Current.Shutdown możesz łatwo skończyć z aplikacją działającą w nieskończoność, jeśli masz kod, który wypycha się z powrotem do programu rozsyłającego.
Marcus Andrén,
Równy jak Application.exit (0);
Sayka,
Z Application.Current.Shutdown();moim Closingwydarzeniem został wywołany, kiedy po prostu chciałem natychmiast wyłączyć aplikację. Więc Environment.Exit(0);był lepszy wybór.
FredM,
64

Jak powiedział wuminqi , Application.Current.Shutdown();jest nieodwracalny i uważam, że zwykle służy do wymuszenia zamknięcia aplikacji w momentach, na przykład gdy użytkownik wylogowuje się lub zamyka system Windows.

Zamiast tego zadzwoń this.close()w głównym oknie. Jest to to samo, co naciśnięcie przycisku Alt+ F4lub zamknięcie przycisku [x] w oknie. Spowoduje to zamknięcie wszystkich innych posiadanych okien i zakończy połączenie Application.Current.Shutdown();, dopóki akcja zamknięcia nie zostanie anulowana. Zobacz dokumentację MSDN na temat zamykania okna .

Ponadto, ponieważ this.close()można ją anulować, można w oknie dialogowym obsługi zdarzenia zamykającego umieścić okno dialogowe potwierdzenia zapisania zmian. Po prostu utwórz moduł obsługi zdarzeń <Window Closing="...">i e.Cancelodpowiednio go zmień . ( Więcej informacji na ten temat można znaleźć w dokumentacji MSDN ).

Allen Pestaluky
źródło
2
+1 Zdecydowałem się na ten, szczególnie, że muszę zapisać otwarte pliki przed zakończeniem aplikacji.
AgentKnopf
2
Należy tutaj zwrócić uwagę na fakt, że Allen wskazał na bardzo ważny fakt: wszystkie pozostałe okna będą zamknięte. Musisz upewnić się, że deklarujesz własność. Jeśli masz okno, które jest uruchomione, a następnie otworzysz kolejne okno, ale jeszcze go nie pokazujesz, po zamknięciu aktywnego okna ukryte okno wymusi działanie aplikacji. Będziesz miał potencjalny wyciek pamięci, chyba że zamkniesz to okno w inny sposób (menedżer zadań itp.). Przetestowałem to.
BK
35

W razie potrzeby skorzystaj z jednego z poniższych:

1.

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

2)

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

Przede wszystkim metody zadzwoni closing eventz Windowklasą i wykonanie może zatrzymać w pewnym momencie (zwykle przyczyną aplikacji umieścić dialogi jak „Czy jesteś pewien?” Lub „ Czy chciałbyś, aby zapisać dane przed zamknięciem? ”, Zanim okno jest całkowicie zamknięta)

3. Ale jeśli chcesz natychmiast zakończyć aplikację bez żadnego ostrzeżenia . Użyj poniżej

   Environment.Exit(0);
Kylo Ren
źródło
18

Oto jak robię moje:

// 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();
    }
}

Dzwonię tylko Application.Current.ShutDown()z głównego okna aplikacji, wszystkie inne okna używają this.Close(). W moim głównym oknie Window_Closing(...)obsługuje prawy górny xprzycisk. Jeśli którakolwiek z metod wymaga okna bliżej, Window_Closing(...)pobiera zdarzenie w celu zamknięcia, jeśli użytkownik potwierdzi.

Powodem, dla którego faktycznie używam Application.Current.Shutdown()w moim oknie głównym jest to, że zauważyłem, że jeśli popełniłem błąd projektowy i nie zadeklarowałem elementu nadrzędnego jednego z moich okien w aplikacji, jeśli okno to zostanie otwarte bez uprzedniego wyświetlenia do ostatniego aktywnego zamknięcia okna, pozostało mi ukryte okno działające w tle. Aplikacja nie zostanie zamknięta. Jedynym sposobem, aby zapobiec całkowitemu wyciekowi pamięci, jest przejście do Menedżera zadań w celu zamknięcia aplikacji. Application.Current.Shutdown()chroni mnie przed niezamierzonymi wadami projektowymi.

To z mojego osobistego doświadczenia. Na koniec użyj tego, co najlepiej pasuje do Twojego scenariusza. To tylko kolejna informacja.

BK
źródło
16

Nie powinno być wiadomości Application.ShutDown();ani .Exit()wiadomości.

Applicationjest klasą statyczną. Nie dotyczy bieżącej aplikacji. Musisz przejść do bieżącej aplikacji, a następnie zamknąć ją w następujący sposób:

Application.Current.Shutdown();
TimothyP
źródło
8

Innym sposobem na to jest:

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

Wymusi to zabicie twojej aplikacji. Zawsze działa, nawet w aplikacjach wielowątkowych.

Uwaga: Uważaj, aby nie utracić niezapisanych danych w innym wątku.

Ali Yousefi
źródło
Wydaje się to niezrozumiałe: „proces zawsze działa” . Czy możesz to naprawić? A przynajmniej wyjaśnij tutaj w komentarzach, co masz na myśli?
Peter Mortensen
Jest to również częściowo niezrozumiałe: wystarczy dbać o aplikację, która zapisuje dane w plikach z innego wątku. Czy możesz to naprawić? A przynajmniej wyjaśnij tutaj w komentarzach, co masz na myśli?
Peter Mortensen,
Czy używasz Tłumacza Google?
Peter Mortensen,
nie, nie mam na myśli, mam na myśli to, że aplikacja działa jako wielowątkowy, a ty używasz Process.Kill to zadziała, ale w inny sposób taki jak ten. zamknij nie działa w aplikacjach wielowątkowych, gdy uruchomiony jest inny wątek.
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
źródło
to nie jest odpowiedź na pytanie, chce on tylko wiedzieć, jak zamknąć aplikację wpf.
mehdi
6

Próbować

App.Current.Shutdown();

Dla mnie

Application.Current.Shutdown(); 

nie działało

Iwona Kubowicz
źródło
6

Według mojego rozumienia Application.Current.Shutdown()ma również swoją wadę.

Jeśli chcesz wyświetlić okno potwierdzenia, aby użytkownicy mogli potwierdzić przy wyjściu lub nie, Application.Current.Shutdown()jest nieodwracalne.

wuminqi
źródło
7
Nie rozumiem tego Możemy jednak uzyskać potwierdzenie użytkownika przed zadzwonieniem Application.Current.Shutdown().
Amsakanna
2
Nie rozumiem, dlaczego powinieneś to potwierdzić. Zbyt wiele potwierdzeń to bardzo zła rzecz. Fakt, że ktoś podjął wysiłek, aby otworzyć menu Plik, przejść do samego końca menu Plik, a następnie kliknąć Wyjdź, jest w dużej mierze potwierdzony, że nie chce już korzystać z aplikacji.
Veer: W moim przypadku pojawia się okno potwierdzenia, ale nawet jeśli wybierzesz „anuluj” w potwierdzeniu, główna aplikacja zostanie zamknięta.
wuminqi
7
JTS: Lepiej jest to projektować indywidualnie. Nasza aplikacja, jeśli są uruchomione zadania, wymuszone wyjście spowoduje szkody, więc lepiej poinformujmy ich w oknie dialogowym potwierdzenia
wuminqi
3

Podsumowując, jest na to kilka sposobów.

1) Zabicie procesu, który pomija finalizację, obsługę błędów itp .:

Process.GetCurrentProcess().Kill();

2) Zamykanie bieżącej aplikacji, co jest prawdopodobnie właściwym sposobem, ponieważ wywołuje zdarzenia wyjścia:

Application.Current.Shutdown();

lub

this.Shutdown();

(gdy jest sklonowany w instancji klasy aplikacji)

3) Zamykanie bieżącej aplikacji (wszystkie formularze muszą zostać zamknięte / zakończone wcześniej):

this.Close(); 

(gdy jest sklonowany w instancji klasy aplikacji)

4) Wyjście ze środowiska, które kończy działanie aplikacji:

Environment.Exit(0);

Możesz także przeczytać tutaj o statusach wyjścia

Burgund
źródło
2

Caliburn o smaku mikro

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
źródło
Co oznacza „Caliburn micro flavored” ?
Peter Mortensen
Jak można to osiągnąć za pomocą Caliburn Micro
Anders
0

Jeśli chcesz wyjść z innego wątku, który nie utworzył obiektu aplikacji, użyj:

System.Windows.Application.Current.Dispatcher.InvokeShutdown();
SoumyaMahunt
źródło
-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;

Alpha-LIon
źródło
2
Witamy w SO, Alpha-LIon! Odradzane są tutaj odpowiedzi tylko na kod, ponieważ nie zapewniają one wglądu w sposób rozwiązania problemu. Zaktualizuj swoje rozwiązanie, wyjaśniając, w jaki sposób Twój kod rozwiązuje problem PO :)
Joel
-3

Z kodu xaml można wywołać predefiniowane polecenie systemowe:

Command="SystemCommands.MinimizeWindowCommand"

Myślę, że powinien to być preferowany sposób ...

Markus Sommerschnee
źródło
Minimalizuj! = Zamknij aplikację. Nie widzę opcji zamykania aplikacji na tej liście. Wydaje się, że więcej zarządzania oknami i zamknięcie okna niekoniecznie oznacza zamknięcie aplikacji. msdn.microsoft.com/en-us/library/…
kenny