Application의 window 제어하기

윈도우용 데스크톱 프로그램은 한 번에 여러 개의 창을 띄울 수 있다는 것을 여러분은 익히 알고 있을 것입니다. 그 중 특정 윈도우를 닫으면 현재 열려있는 윈도우가 닫히고 최종적으로 프로그램이 완전히 종료하게 됩니다. 여러 개의 윈도우중 그 어느 윈도우를 닫더라도 현재 실행중인 프로그램이 종료된다면 프로그램의 성능상에 심각한 문제가 발생 할 수 있습니다. 또 프로그램에는 반드시 메인 윈도우가 존재해야 하며 서브 윈도우를 제어할 수 있어야 합니다.
using System;
using System.Windows;
using System.Windows.Input;
 
namespace Chapter1
{
    class ThrowWindowParty : Application
    {
        [STAThread]
        public static void Main()
        {
            ThrowWindowParty app = new ThrowWindowParty();
            app.Run();
        }
 
        protected override void OnStartup(StartupEventArgs e)
        {
            Window winMain = new Window();
            winMain.Title = "Main Window";
            winMain.MouseDown += new MouseButtonEventHandler(winMain_MouseDown);
            winMain.Show();
 
            for (int i = 0; i < 2; i++)
            {
                Window win = new Window();
                win.Owner = winMain;
                win.Title = "Extra Window No." + (i + 1);
                win.Show();
            }
        }
}
}

위 프로그램에서 첫 번째 중요한 사실은 OnStartup() 이벤트에서 생성된 3개의 창은 이 응용프로그램에서 모두 동등하다는 것입니다. 그 어떤 윈도우라도 클릭하게 되면 선택된 윈도우는 가장 앞에 자리하게 됩니다. 어떤 순서로도 닫을 수 있으며 가장 마지막에 윈도우가 닫히면 프로그램은 종료됩니다.

 그러나 여기서 간과할 수 없는 것은 Application 객체의 MainWindow 프로퍼티를 살펴보면, Show가 호출되는 첫 창이 그 응용프로그램에서 메인 윈도우로 간주되는 것을 알 수 있습니다.

 프로그램을 실행시켜 보면 윈도우 작업 표시줄에 3개의 윈도우가 모두 표시되 있는 것을 확인할 수 있습니다.

사용자 삽입 이미지

for 루프 안에 다음 구문을 삽입하면 "Main Window" 란 제목을 가진 윈도우만 남게 됩니다.

for (int i = 0; i < 2; i++)
{
Window win = new Window();
    win.Owner = winMain;
    win.Title = "Extra Window No." + (i + 1);
    win.ShowInTaskbar = false;
    win.Show();
}

그러나 이 같은 경우 "Main Window" 윈도우를 닫을 경우 윈도우 작업표시줄에 있던 항목은 사라지지만 여전히 응용 프로그램은 계속 실행중 입니다. 물론 2개의 다른 창도 그대로 프로세스에 남아있겠지요 ~~~

 일반적으로 윈도우 프로그램은 Run 메소드가 반환될 때 프로그램이 종료되는데, 마지막 윈도우를 닫을 경우 Run메소드가 반환됩니다. 만약 메인윈도우가 지정되고 이 윈도우가 닫힐 경우만 프로르램이 종료되도록 설정하고 싶다면 Application 클래스의 ShotdownMode 프로퍼티를 OnMainWindowClose로 설정하면 됩니다. (기본값은 OnLastWindowClose 입니다)

ShutdownMode
프로퍼티


ShutdownMode

OnLastWindowClose

마지막 윈도우가 닫힐 경우

OnMainWindowClose

메인 윈도우를 닫을 경우

OnExplicitShutdown

Shutdown 메소드를 명시적으로 호출할 경우

 윈도우 응용프로그램의 시작점인 Main() 메소드에서 상속받은 Application 클래스안에 있는 ShutdownMode 프로퍼티를 사용하면 됩니다. 여기서 중요한 것은 Run메소드가 실행되기 전에 ShutdownMode 프로퍼티가 설정되어야 합니다.

[STAThread]
public static void Main()
{
ThrowWindowParty app = new ThrowWindowParty();
    app.ShutdownMode = ShutdownMode.OnMainWindowClose;
    app.Run();
}

반면 재정의(override) OnStartup 이벤트 안에서는 this 키워드만 붙이면 이벤트 안의 어느곳이든 ShutdownMode 프로퍼티 설정이 가능합니다. (this 키워드는 생략할 수 있으므로 그냥 프로퍼티 이름만 적어도 됩니다.)

protected override void OnStartup(StartupEventArgs e)
{
     Window winMain = new Window();
     winMain.Title = "Main Window";
     winMain.MouseDown += new MouseButtonEventHandler(winMain_MouseDown);
     // this.ShutdownMode = ShutdownMode.OnMainWindowClose;
     ShutdownMode = ShutdownMode.OnMainWindowClose;
     winMain.Show();
 
    ……… 생략
 }

이제 메인 윈도우가 닫힐 때만 Run 메소드가 반환되고 프로그램이 종료됩니다. 마지막으로 메인윈도우를 지정하는 구분을 알아보면 다음과 같습니다. 다음 구문을 OnStartup 이벤트의for 루프 안에 추가합니다.

MainWindow = win;

마지막으로 지금까지 추가된 모든 구문을 제거하고 여러 윈도우들에 대한 계층 구조를 만드는 또 다른 방법을 알아보겠습니다. For 루프 안에 다음 구문을 추가합니다. Window 클래스에 정의된 Owner 프로퍼티를 이용하여 메인으로 지정할 윈도우를 지정하는 합니다. Owner은 소유자라는 뜻으로 기본값은 null 이며 나머지 윈도우를 소유하고 제어할 수 있습니다. 소유자 윈도우를 최소화하면 모든 윈도우가 화면에서 사라지고 소유자 윈도우를 닫으면 나머지 모든 윈도우도 자동으로 닫히게 됩니다.

Win.Owner = winMain;

 참고서적 : 찰스 페졸트의 WPF