Приложение WPF не закрывается при закрытии главного окна
Я привык к программированию WinForms в Visual Studio, но я хотел дать WPF попробовать.
я добавил еще одно окно в свой проект под названием Window01. Главное окно называется MainWindow. Перед public MainWindow() конструктор я объявляю Window01:
Window01 w1;
теперь я создаю экземпляр этого окна в:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
w1 = new Window01();
}
у меня есть кнопка, где показано окно: w1.ShowDialog();.
"забавная" вещь здесь заключается в том, что если я запускаю приложение (с отладкой) и выйдите из него через несколько секунд (я ничего не делаю в приложении), Visual Studio не прекращает отладку, как будто приложение все еще работает.
если я передвину линию w1 = new Window01(); к методу нажатия кнопки, что означает чуть выше ShowDialog(), Visual Studio ведет себя правильно - то есть отладка останавливается при выходе из приложения.
почему такое странное поведение?
5 ответов:
в своем
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).A
ShutdownModeнаOnMainWindowCloseзаставляет WPF неявно вызывать Shutdown при закрытии главного окна, даже если другие окна в настоящее время открыты.срок службы некоторых приложений может не зависеть от того, когда закрыто главное окно или последнее окно, или не может будьте зависимы от windows вообще. Для этих сценариев необходимо установить
ShutdownModeсвойствоOnExplicitShutdown, что требует явногоShutdownвызов метода для остановки приложения. В противном случае приложение продолжает работать в фоновом режиме.
ShutdownModeможно настроить декларативно из XAML или программно из кода.это свойство доступно только из потока, который создал
я рад, что вы получили свой ответ, но ради других я отвечу на ваш вопрос, а также добавлю некоторую информацию.
Шаг 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:MainWindow = mainWindow;в XAML
перейти к
ApplicationXAML, как вы сделали в шаге 1, и укажите, чтоApplication.MainWindow' s значение является вашимWindow:MainWindow = "mainWindow";
альтернатива
я не думаю, что это лучший подход, просто потому, что WPF не хочет, чтобы вы это делали (так что это
Application' sShutdownMode), но вы можете просто использовать событие / переопределить метод события (OnEventHappened).перейдите к кодовому файлу главного окна и добавьте:
protected override void OnClosed(EventArgs e) { base.OnClosed(e); App.Current.Shutdown(); }
потому что по умолчанию режим отключения в WPF приложение OnLastWindowClose, что означает, что приложение останавливается при закрытии последнего окна.
при создании экземпляра нового объекта Window он автоматически добавляется в список Windows в приложение. Итак, проблема заключалась в том, что ваше приложение создавало два окна при запуске - главное окно и еще не показанное Window01- и если вы только закрыли главное окно, Window01 будет держать ваше приложение работает.
обычно вы создаете объект window в том же методе, который будет вызывать его ShowDialog, и вы будете создавать новый объект window каждый раз, когда отображается диалоговое окно.
похоже, что я столкнулся, когда я создал второе окно в качестве диалогового окна. Когда второе окно было открыто, а затем закрыто, а затем Главное окно было закрыто, приложение продолжало работать (в фоновом режиме). Я добавил (Или подтвердил) следующее В моем приложении.xaml:
<Application x:Class="XXXXXXX.App" ... StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"> <Application.MainWindow > <NavigationWindow Source="MainWindow.xaml" Visibility="Visible" /> </Application.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 находит только одно окно-диалоговое окно, а не основное.
у меня было "это.Close () "работает в методе, который закрыл диалоговое окно, и у меня был" dlgwin.Close ()", который появился после " dlgwin.ShowDialog ()", и это не сработало. Даже не "dlgwin = null".
Итак, почему бы этот диалог не закрыть без это лишние вещи? Ну что ж. Эта работа.
я наткнулся на этот вопрос при поиске чего-то еще, и я был удивлен, что не смог увидеть ни одного из предложенных ответов, упоминающих о
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затем....
- минимизация
MainWindowтакже минимизируетAdditionalWindow- восстановление
MainWindowтакже восстановитьAdditionalWindow- закрытие
MainWindowзакрытьAdditionalWindow, а закрывающийAdditionalWindowне будет рядомMainWindowAdditioanlWindowникогда не будет" потеряться " под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(); } }
Comments