Programing

주 창을 닫을 때 WPF 앱이 종료되지 않음

lottogame 2020. 11. 17. 07:38
반응형

주 창을 닫을 때 WPF 앱이 종료되지 않음


저는 Visual Studio에서 WinForms 프로그래밍에 익숙하지만 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가 제대로 작동하는 것입니다. 즉, 응용 프로그램을 종료하면 디버깅이 중지됩니다.

왜 이렇게 이상한 행동을하나요?


에서 다음을 MainWindow.xaml.cs수행하십시오.

protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);

    Application.Current.Shutdown();
}

이 링크 당 ShutdownModeXAML에서 설정할 수도 있습니다 .

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하면 OnLastWindowCloseWPF (Windows Presentation Foundation)는 현재 인스턴스화 된 창이 주 창으로 설정되어 있더라도 응용 프로그램의 마지막 창이 닫힐 때 암시 적으로 Shutdown을 호출합니다 (MainWindow 참조).

ShutdownModeOnMainWindowClose원인은 MainWindow를 닫히고는, 다른 창은 현재 열려있는 경우에도 때 암시 적으로 종료를 호출하는 WPF.

일부 응용 프로그램의 수명은 주 창 또는 마지막 창이 닫히는시기에 의존하지 않거나 창에 전혀 의존하지 않을 수 있습니다. 이러한 시나리오의 경우 ShutdownMode속성을 로 설정해야 합니다.이 경우 애플리케이션을 중지하려면 OnExplicitShutdown명시적인 Shutdown메서드 호출 이 필요합니다 . 그렇지 않으면 응용 프로그램이 백그라운드에서 계속 실행됩니다.

ShutdownMode XAML에서 선언적으로 또는 코드에서 프로그래밍 방식으로 구성 할 수 있습니다.

이 속성은 Application개체 를 만든 스레드에서만 사용할 수 있습니다 .


귀하의 경우 기본값을 사용하고 있기 때문에 앱이 닫히지 않습니다 OnLastWindowClose.

사용자가 설정 한 경우 ShutdownModeOnLastWindowClose어떤 현재 인스턴스 창 메인 창으로 설정 한 경우에도 응용 프로그램 닫히고의 마지막 창 (볼 때, WPF는 암시 적으로 종료를 호출 MainWindow).

새 창을 열고 닫지 않기 때문에 shutdown이 호출되지 않습니다.


답변을 받으 셨다니 기쁩니다.하지만 다른 사람들을 위해 질문에 답하여 정보를 추가하겠습니다.


1 단계

첫째, 주 창이 닫힐 때 프로그램을 종료하려면이 동작이 기본값 인 WinForms가 아니기 때문에 지정해야합니다.

(WPF의 기본값은 마지막 창이 닫힐 때입니다.)

코드에서

진입 점의 애플리케이션 인스턴스로 이동합니다 (VS 2012의 WPF 프로그램에서는 기본값이 내부 App.xaml중첩되어 있으므로 내부로 이동하여 App.xaml.cs생성자로 이동하고 생성합니다).

생성자에서 사용자 지정 Application의가 ShutdownMode있어야한다 ShutdownMode. OnLastWindowClose.

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

XAML에서

당신의 이동 App.xaml루트는이 VS 2012 기본적으로 만든 파일 (또는 직접 작성) Application, 당신의 것을 내 지정 Application의가 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 애플리케이션을 작성한 것 같습니다) 메인 창은 애플리케이션에서 메인 창으로 인식되지 않을 것입니다. 그래서 그것을 지정하십시오.

코드에서

Go to the application's constructor as you did in Step 1, and specify that Application.MainWindow's value is your Window:

MainWindow = mainWindow;

In XAML

Go to the Application XAML as you did in Step 1, and specify that Application.MainWindow's value is your Window:

MainWindow = "mainWindow";

Alternative

I don't think this is the best approach, just because WPF doesn't want you to do this (so it has Application's ShutdownMode), but you can just use an event / override an event method (OnEventHappened).

Go to the MainWindow's code-behind file and add:

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);

        App.Current.Shutdown();
    }

Because the default shutdown mode in a WPF application is OnLastWindowClose, which means the application stops when the last window closes.

When you instantiate a new Window object, it automatically gets added to the list of windows in the application. So, the problem was that your application was creating two windows when it started - the MainWindow and the not-yet-shown Window01 - and if you only closed the MainWindow, the Window01 would keep your application running.

Normally, you will create a window object in the same method that is going to call its ShowDialog, and you will create a new window object each time the dialog is shown.


It looks like something I ran into when I created a second window to act as a dialog box. When the second window was opened and then closed and then the main window was closed, the app kept running (in the background). I added (or confirmed) the following in my App.xaml:

<Application x:Class="XXXXXXX.App"
             ...  
             StartupUri="MainWindow.xaml"
             ShutdownMode="OnMainWindowClose">
    <Application.MainWindow >
        <NavigationWindow Source="MainWindow.xaml" Visibility="Visible" />
    </Application.MainWindow>

No joy.

So, I finally went into my "MainWindow.xaml" and added a "Closed" property to the Window which went to a "MainWind_Closed" method that looks like the following:

 private void MainWind_Closed(object sender, EventArgs e)
        {
            foreach ( Window w in App.Current.Windows )
            {
                if (w.DataContext != this)
                    w.Close();
            }
        }

Running through the debugger, it looks like the only window that shows up is the window I created as a dialog--in other words, the foreach loop only finds one window--the dialog, not the main.

I had "this.Close()" running in the method that closed the dialog, and I had a "dlgwin.Close()" that came after the "dlgwin.ShowDialog()", and that didn't work. Not even a "dlgwin = null".

So, why wouldn't that dialog close without this extra stuff? Oh well. This works.


I stumbled across this Question when searching for something else and I was surprised that I could not see any of the proposed answers mentioning about Window.Owner.

    {
       var newWindow = new AdditionalWindow();
       newWindow.Owner = Window.GetWindow(this);

       // then later on show the window with Show() or ShowDialog()
    }

A call to Window.GetWindow(this) is quite useful in View of an MVVM application when you are far down the visual tree not knowing where you have been instantiated, it can be called by supplying any FrameWork element (e.g. UserContol, Button, Page). Obviously if you have a direct reference to the window then use that or even Application.Current.MainWindow.

This is quite a powerful relationship that has a number of useful benefits that you might not realise to begin with (assuming you have not specifically coded separate windows to avoided these relationships).

If we call your main window MainWindow and the second window as AdditionalWindow then....

  1. Minimising the MainWindow will also minimise AdditionalWindow
  2. Restoring MainWindow will also restore AdditionalWindow
  3. Closing MainWindow will close AdditionalWindow, but closing AdditionalWindow will not close MainWindow
  4. AdditioanlWindow will never get "lost" under MainWindow, i.e. AddditionalWindow always shows above MainWindow in the z-order if you used Show() to display it (quite useful!)

One thing to note though, if you have this relationship, then the Closing event on the AdditionalWindow is not called, so you'd have to manually iterate over the OwnedWindows collection. e.g. Create a way to call each window via a new Interface, or base class method.

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

참고URL : https://stackoverflow.com/questions/9992119/wpf-app-doesnt-shut-down-when-closing-main-window

반응형