Приложение 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 ведет себя правильно - то есть отладка останавливается при выходе из приложения.



почему такое странное поведение?

990   5  

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 ' s ShutdownMode должно быть ShutdownMode.OnLastWindowClose.

    public App()
    {
        ShutdownMode = ShutdownMode.OnLastWindowClose;
    }

в XAML

иди к своему App.xaml файл, который VS 2012 создан по умолчанию (или создать это вы сами) Корень-это Application, указать, что внутри вашего Application ' s ShutdownMode должно быть 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

перейти к Application XAML, как вы сделали в шаге 1, и укажите, что Application.MainWindow ' s значение является вашим Window:

MainWindow = "mainWindow";

альтернатива

я не думаю, что это лучший подход, просто потому, что WPF не хочет, чтобы вы это делали (так что это Application ' s ShutdownMode), но вы можете просто использовать событие / переопределить метод события (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 затем....

  1. минимизация MainWindow также минимизирует AdditionalWindow
  2. восстановление MainWindow также восстановить AdditionalWindow
  3. закрытие MainWindow закрыть AdditionalWindow, а закрывающий AdditionalWindow не будет рядом MainWindow
  4. 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();
        }        
    }

Comments

    Ничего не найдено.