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.

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.


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)

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 ).


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);


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.


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

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.


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

to nie jest odpowiedź na pytanie, chce on tylko wiedzieć, jak zamknąć aplikację wpf.
— mehdi


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.


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


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

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

-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;


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 ...


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.