W swoim MainWindow.xaml.cs
, spróbuj zrobić to:
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Application.Current.Shutdown();
}
Za pomocą tego linku możesz również ustawić ShutdownMode
w języku XAML:
http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnExplicitShutdown"
>
</Application>
Aplikacje przestają działać tylko wtedy, gdy wywoływana jest Shutdown
metoda Application
. Zamknięcie może nastąpić niejawnie lub jawnie, zgodnie z wartością ShutdownMode
właściwości.
Jeśli ustawisz ShutdownMode
na OnLastWindowClose
, Windows Presentation Foundation (WPF) niejawnie wywołuje Shutdown po zamknięciu ostatniego okna w aplikacji, nawet jeśli jakiekolwiek aktualnie utworzone okna są ustawione jako okno główne (zobacz MainWindow).
A ShutdownMode
z OnMainWindowClose
powoduje, że WPF niejawnie wywołuje Shutdown po zamknięciu MainWindow, nawet jeśli inne okna są obecnie otwarte.
Czas życia niektórych aplikacji może nie zależeć od tego, kiedy główne lub ostatnie okno jest zamknięte, lub może w ogóle nie zależeć od okien. W tych scenariuszach należy ustawić ShutdownMode
właściwość na OnExplicitShutdown
, która wymaga jawnego Shutdown
wywołania metody, aby zatrzymać aplikację. W przeciwnym razie aplikacja będzie nadal działać w tle.
ShutdownMode
można skonfigurować deklaratywnie z XAML lub programowo z kodu.
Ta właściwość jest dostępna tylko w wątku, który utworzył Application
obiekt.
W Twoim przypadku aplikacja nie zamyka się, ponieważ prawdopodobnie używasz domyślnej OnLastWindowClose
:
Jeśli ustawisz ShutdownMode
na OnLastWindowClose
, WPF niejawnie wywoła Shutdown po zamknięciu ostatniego okna w aplikacji, nawet jeśli jakiekolwiek aktualnie utworzone okna są ustawione jako okno główne (zobacz MainWindow
).
Ponieważ otwierasz nowe okno, a nie je zamykasz, wyłączenie nie jest wywoływane.
Application.Current.Shutdown()
spowoduje natychmiastowe zamknięcie aplikacji, podobnie jak zakończenie procesu na pasku zadań. To jak strzelanie do kogoś, zanim powie ostatnie słowo :) .. Nie polecam.Cieszę się, że dostałeś odpowiedź, ale dla dobra innych odpowiem również na twoje pytanie, aby dodać trochę informacji.
Krok 1
Po pierwsze, jeśli chcesz, aby program kończył pracę po zamknięciu okna głównego, musisz to określić, ponieważ nie jest to WinForms, w którym to zachowanie jest domyślne.
(Domyślnie w WPF jest zamknięcie ostatniego okna)
W kodzie
Przejdź do wystąpienia aplikacji w punkcie wejścia (w programie WPF VS 2012 wartość domyślna jest zagnieżdżona w środku
App.xaml
, więc przejdź do niego i przejdź doApp.xaml.cs
i utwórz konstruktor).W konstruktorze określić, że
Application
„sShutdownMode
powinno byćShutdownMode
.OnLastWindowClose
.public App() { ShutdownMode = ShutdownMode.OnLastWindowClose; }
W XAML
Przejdź do
App.xaml
pliku, który VS 2012 domyślnie utworzone (lub utwórz go samodzielnie) Korzeń jestApplication
określić wewnątrz, żeApplication
„sShutdownMode
powinno byćShutdownMode
.OnLastWindowClose
.<Application x:Class="WpfApplication27.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose">
Jeśli to zadziała, gotowe; możesz przestać czytać.
Krok 2
Jeśli powyższe nie zadziałało (myślę, że napisałeś aplikację WPF od zera), główne okno prawdopodobnie nie jest znane aplikacji jako główne. Więc to też określ.
W kodzie
Przejdź do konstruktora aplikacji, tak jak w kroku 1, i określ to
Application
.MainWindow
wartość toWindow
:W XAML
Przejdź do
Application
kodu XAML, tak jak w kroku 1, i określ toApplication
.MainWindow
wartość toWindow
:MainWindow = "mainWindow";
Alternatywny
Nie sądzę, że jest to najlepsze podejście, tylko dlatego, że WPF nie chce, aby to zrobić (a więc ma
Application
„sShutdownMode
), ale można po prostu użyć zdarzenie / nadpisać metodę zdarzeń (OnEventHappened).Przejdź do pliku związanego z kodem MainWindow i dodaj:
protected override void OnClosed(EventArgs e) { base.OnClosed(e); App.Current.Shutdown(); }
źródło
MainWindow
na wystąpienie okna głównego, ustawShutdownMode
naShutdownMode.OnMainWindowClose
, wywołajMainWindow.Show()
oddzwonienie doStartup
zdarzeniaApp
. Jest to najbardziej minimalne rozwiązanie, które wymyśliłem, które działa zgodnie z oczekiwaniami przynajmniej w .NET Core 3 z WPF.Ponieważ domyślny tryb zamykania w aplikacji WPF jest OnLastWindowClose, co oznacza, że aplikacja zatrzymuje się po zamknięciu ostatniego okna.
Kiedy tworzysz wystąpienie nowego obiektu Window, jest on automatycznie dodawany do pliku listy okien w aplikacji. Tak więc problem polegał na tym, że aplikacja tworzyła dwa okna podczas uruchamiania - MainWindow i jeszcze nie pokazane Window01 - i gdybyś zamknął tylko MainWindow, Window01 utrzymywałby twoją aplikację w ruchu.
Zwykle tworzysz obiekt okna tą samą metodą, która wywołuje jego ShowDialog, i tworzysz nowy obiekt okna za każdym razem, gdy jest wyświetlane okno dialogowe.
źródło
Natknąłem się na to pytanie, szukając czegoś innego i byłem zaskoczony, że nie widziałem żadnej z proponowanych odpowiedzi, o których mowa
Window.Owner
.{ var newWindow = new AdditionalWindow(); newWindow.Owner = Window.GetWindow(this); // then later on show the window with Show() or ShowDialog() }
Wywołanie
Window.GetWindow(this)
jest bardzo przydatna z punktu widzenia aplikacji MVVM, gdy jesteś daleko w dół drzewa wizualnej nie wiedząc, gdzie zostałeś instancji, może być wywołana przez dostarczenie jakiegokolwiekFrameWork
elementu (npUserContol
,Button
,Page
). Oczywiście, jeśli masz bezpośrednie odniesienie do okna, użyj tego lub nawetApplication.Current.MainWindow
.Jest to dość potężna relacja, która ma wiele przydatnych korzyści, z których możesz nie zdawać sobie sprawy (zakładając, że nie zakodowałeś osobnych okien, aby uniknąć tych relacji).
Jeśli nazwiemy Twoje główne okno
MainWindow
i drugie okno tak jakAdditionalWindow
wtedy ....MainWindow
woli również zminimalizowaćAdditionalWindow
MainWindow
również przywróciAdditionalWindow
MainWindow
zostanie zamknięteAdditionalWindow
, ale zamknięcieAdditionalWindow
nie zostanie zamknięteMainWindow
AdditioanlWindow
nigdy się nie „zgubi” podMainWindow
, tzn.AddditionalWindow
zawsze wyświetla się powyżejMainWindow
w kolejności z, jeśli był wcześniejShow()
wyświetlany (całkiem przydatne!)Należy jednak zauważyć, że jeśli masz taką relację,
Closing
zdarzenie wAdditionalWindow
elemencie nie jest wywoływane, więc musisz ręcznie iterować poOwnedWindows
kolekcji. np. Stwórz sposób wywoływania każdego okna za pomocą nowego interfejsu lub metody klasy bazowej.private void MainWindow_OnClosing(object sender, CancelEventArgs e) { foreach (var window in OwnedWindows) { var win = window as ICanCancelClosing; // a new interface you have to create e.Cancel |= win.DoYouWantToCancelClosing(); } }
źródło
Żadne z powyższych nie zadziałało dla mnie, może dlatego, że nasz projekt wykorzystuje Prism. Skończyło się na użyciu tego w App.XAML.cs
protected override void OnExit(ExitEventArgs e) { base.OnExit(e); Process.GetCurrentProcess().Kill(); }
źródło
Wygląda na coś, na co natknąłem się, gdy utworzyłem drugie okno, które pełniło rolę okna dialogowego. Gdy drugie okno zostało otwarte, a następnie zamknięte, a następnie główne okno zostało zamknięte, aplikacja nadal działała (w tle). Dodałem (lub potwierdziłem) następujące elementy w moim App.xaml:
<Application x:Class="XXXXXXX.App" ... StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"> <Application.MainWindow > <NavigationWindow Source="MainWindow.xaml" Visibility="Visible" /> </Application.MainWindow>
Brak przyjemności.
W końcu przeszedłem do mojego „MainWindow.xaml” i dodałem właściwość „Closed” do okna, która przeszła do metody „MainWind_Closed”, która wygląda następująco:
private void MainWind_Closed(object sender, EventArgs e) { foreach ( Window w in App.Current.Windows ) { if (w.DataContext != this) w.Close(); } }
Po uruchomieniu debugera wygląda na to, że jedynym oknem, które się pojawia, jest okno, które utworzyłem jako okno dialogowe - innymi słowy, pętla foreach znajduje tylko jedno okno - okno dialogowe, a nie główne.
Miałem "this.Close ()" uruchomioną w metodzie, która zamknęła okno dialogowe i miałem "dlgwin.Close ()", który pojawił się po "dlgwin.ShowDialog ()" i to nie zadziałało. Ani nawet "dlgwin = null".
Dlaczego więc to okno dialogowe nie zamknęło się bez tych dodatkowych rzeczy? No cóż. To działa.
źródło