В вашем MainWindow.xaml.cs
попробуйте сделать это:
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Application.Current.Shutdown();
}
По этой ссылке вы также можете установить ShutdownMode
в 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>
Приложения перестают работать только при вызове Shutdown
метода Application
. Завершение работы может происходить неявно или явно, в зависимости от значения ShutdownMode
свойства.
Если установлено ShutdownMode
значение OnLastWindowClose
, Windows Presentation Foundation (WPF) неявно вызывает Shutdown при закрытии последнего окна в приложении, даже если какие-либо окна, созданные в данный момент, установлены в качестве главного окна (см. MainWindow).
По одной ShutdownMode
из OnMainWindowClose
причин WPF неявно вызывает Shutdown при закрытии MainWindow, даже если в данный момент открыты другие окна.
Время жизни некоторых приложений может не зависеть от того, когда было закрыто главное или последнее окно, или вообще не зависеть от окон. Для этих сценариев вам необходимо установить для ShutdownMode
свойства значение OnExplicitShutdown
, что требует явного Shutdown
вызова метода для остановки приложения. В противном случае приложение продолжит работу в фоновом режиме.
ShutdownMode
можно настроить декларативно из XAML или программно из кода.
Это свойство доступно только из потока, создавшего Application
объект.
В вашем случае приложение не закрывается, потому что вы, вероятно, используете значение по умолчанию OnLastWindowClose
:
Если установлено ShutdownMode
значение OnLastWindowClose
, WPF неявно вызывает Shutdown при закрытии последнего окна в приложении, даже если какие-либо окна, созданные в данный момент, установлены в качестве главного окна (см MainWindow
. Раздел "Ресурсы" ).
Поскольку вы открываете новое окно, но не закрываете его, выключение не вызывается.
Application.Current.Shutdown()
немедленно завершит работу приложения, как завершение процесса на панели задач. Это как выстрелить в кого-то, прежде чем он скажет свое последнее слово :) .. Я бы не рекомендовал.Я рад, что вы получили свой ответ, но ради других я отвечу и на ваш вопрос, чтобы добавить некоторую информацию.
Шаг 1
Во-первых, если вы хотите, чтобы ваша программа закрывалась при закрытии главного окна, вам нужно указать, поскольку это не WinForms, где это поведение по умолчанию.
(По умолчанию в WPF закрывается последнее окно)
В коде
Перейдите к экземпляру приложения в точке входа (в программе WPF VS 2012 значение по умолчанию вложено внутрь
App.xaml
, поэтому войдите в него и перейдите к конструкторуApp.xaml.cs
и создайте его).В конструкторе указать , что ваши
Application
«sShutdownMode
должно бытьShutdownMode
.OnLastWindowClose
.public App() { ShutdownMode = ShutdownMode.OnLastWindowClose; }
В XAML
Перейдите к
App.xaml
файлу , который VS 2012 , созданный по умолчанию (или создать его самостоятельно) Корень являетсяApplication
указать внутри , что вашиApplication
«sShutdownMode
должно быть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">
Если это работает, все готово; можешь перестать читать.
Шаг 2
Если вышеуказанное не сработало (я думаю, вы написали приложение WPF с нуля), главное окно, вероятно, не известно приложению как главное окно. Так что укажите и это.
В коде
Перейдите в конструктор приложения, как вы делали на шаге 1, и укажите это
Application
.MainWindow
ценность - это вашеWindow
:В XAML
Перейдите к
Application
XAML, как вы делали на шаге 1, и укажите этоApplication
.MainWindow
ценность - это вашеWindow
:MainWindow = "mainWindow";
Альтернатива
Я не думаю , что это лучший подход, просто потому , что WPF не хочет , чтобы вы это сделать (так он имеет
Application
«sShutdownMode
), но вы можете просто использовать событие / переопределить метод события (OnEventHappened).Перейдите в файл кода программной части MainWindow и добавьте:
protected override void OnClosed(EventArgs e) { base.OnClosed(e); App.Current.Shutdown(); }
источник
MainWindow
экземпляр главного окна, устанавливаюShutdownMode
значениеShutdownMode.OnMainWindowClose
, вызываюMainWindow.Show()
обратный вызов дляStartup
событияApp
. Это самое минимальное решение, которое я придумал, которое работает должным образом, по крайней мере, в .NET Core 3 с WPF.Поскольку режим завершения работы по умолчанию в приложении WPF - OnLastWindowClose, это означает, что приложение останавливается, когда закрывается последнее окно.
Когда вы создаете экземпляр нового объекта Window, он автоматически добавляется в список окон в приложении. Итак, проблема заключалась в том, что ваше приложение при запуске создавало два окна - MainWindow и еще не показанное Window01 - и если вы закроете только MainWindow, Window01 продолжит работу вашего приложения.
Обычно вы создаете объект окна в том же методе, который будет вызывать его ShowDialog, и вы будете создавать новый объект окна каждый раз, когда отображается диалог.
источник
Я наткнулся на этот вопрос, когда искал что-то еще, и был удивлен, что не увидел ни одного из предложенных ответов, упоминающих о
Window.Owner
.{ var newWindow = new AdditionalWindow(); newWindow.Owner = Window.GetWindow(this); // then later on show the window with Show() or ShowDialog() }
Вызов
Window.GetWindow(this)
является весьма полезным с точки зрения приложения MVVM , когда вы далеко вниз по визуальному дереву , не зная , где ты был создан экземпляр, он может быть вызван путем подачи любогоFrameWork
элемента (напримерUserContol
,Button
,Page
). Очевидно, если у вас есть прямая ссылка на окно, используйте это или дажеApplication.Current.MainWindow
.Это довольно мощная взаимосвязь, которая имеет ряд полезных преимуществ, которые вы могли не осознавать с самого начала (при условии, что вы специально не закодировали отдельные окна, чтобы избежать этих взаимосвязей).
Если мы назовем ваше главное окно
MainWindow
и второе окно какAdditionalWindow
then ....MainWindow
воли также минимизируетAdditionalWindow
MainWindow
также восстановитAdditionalWindow
MainWindow
закроетсяAdditionalWindow
, но закрытиеAdditionalWindow
не закроетсяMainWindow
AdditioanlWindow
никогда не потеряется внизуMainWindow
, т.е.AddditionalWindow
всегда отображается вверхуMainWindow
в z-порядке, если вы использовали егоShow()
для отображения (весьма полезно!)Однако следует отметить одну вещь: если у вас есть эта связь, то
Closing
событие вAdditionalWindow
не вызывается, поэтому вам придется вручную перебиратьOwnedWindows
коллекцию. например, создать способ вызова каждого окна через новый интерфейс или метод базового класса.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(); } }
источник
Ничего из вышеперечисленного у меня не сработало, возможно, потому, что в нашем проекте используется Prism. Итак, в итоге я использовал это в App.XAML.cs
protected override void OnExit(ExitEventArgs e) { base.OnExit(e); Process.GetCurrentProcess().Kill(); }
источник
Похоже, я столкнулся с чем-то, когда создавал второе окно, действующее как диалоговое окно. Когда второе окно было открыто, а затем закрыто, а затем закрылось главное окно, приложение продолжало работать (в фоновом режиме). Я добавил (или подтвердил) следующее в свой App.xaml:
<Application x:Class="XXXXXXX.App" ... StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"> <Application.MainWindow > <NavigationWindow Source="MainWindow.xaml" Visibility="Visible" /> </Application.MainWindow>
Никакой радости.
Итак, я наконец зашел в свой «MainWindow.xaml» и добавил свойство «Closed» к окну, которое перешло к методу «MainWind_Closed», который выглядит следующим образом:
private void MainWind_Closed(object sender, EventArgs e) { foreach ( Window w in App.Current.Windows ) { if (w.DataContext != this) w.Close(); } }
Проходя через отладчик, похоже, что единственное окно, которое появляется, - это окно, которое я создал как диалог - другими словами, цикл foreach находит только одно окно - диалог, а не главное.
У меня был «this.Close ()», работающий в методе, закрывающем диалог, и «dlgwin.Close ()», который шел после «dlgwin.ShowDialog ()», и это не сработало. Даже "dlgwin = null".
Итак, почему бы этот диалог не закрыть без этого дополнительного материала? Ну что ж. Это работает.
источник