반응형

Window를 상속해 클래스를 정의하는 것도 가능하다.

다음 예제는 세 개의 클래스가 있고, 세 개의 소스 코드 파일이 있다. 

[InheritAppAndWindow.cs]

Main에서 MyApplication 타입의 객체를 생성하고, 이 객체의 Run을 호출한다.

using System;
using System.Windows;
using System.Windows.Input;

namespace InheritAppAndWindow
{
    public class InheritAppAndWindow
    {
        [STAThread]
        public static void Main()
        {
            MyApplication app = new MyApplication();
            app.Run();
        }
    }
}

[MyApplication.cs]

OnStartup 메소드를 오버라이딩한 부분에서 MyWindow 타입의 객체를 생성하고 있다.

using System;
using System.Windows;
using System.Windows.Input;

namespace InheritAppAndWindow
{
    public class MyApplication : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            MyWindow win = new MyWindow();
            win.Show();
        }
    }
}

[MyWindow.cs]

Window를 상속받는 클래스는 일반적으로 생성자에서 그 클래스를 초기화한다. 예제에서는 Title 프로퍼티만 초기화한다. 프로퍼티 이름 앞에 객체의 이름을 따로 쓰지 않았는데, MyWindow가 Window를 상속받기 때문이다.

using System;
using System.Windows;
using System.Windows.Input;

namespace InheritAppAndWindow
{
    public class MyWindow : Window
    {
        public MyWindow()
        {
           this.Title = "Inherit App & Window";
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            string strMessage = string.Format("Window clicked with {0} button at point ({1})", e.ChangedButton, e.GetPosition(this));
            MessageBox.Show(strMessage, Title);
        }
    }
}

 

InheritAppAndWindow.zip
0.02MB

반응형
반응형

명령 행 인자는 문자열의 배열 형태로 Main에 전달된다. 이 문자열의 배열은 OnStartUp 메소드에서도 사용할 수 있다. StartupEventArgs 인자의 Args 프로퍼티를 참조하면 된다.

Application에 MainWindow란 이름의 프로퍼티가 있다는 것은 프로그램이 여러 개의 창을 가질 수 있음을 시사하고 있는데, 이는 사실이다. 대화 상자를 그 좋은 예로 들 수 있다. 대화 상자는 기본적으로 Window 객체이지만 표시 방식이 조금 다르다는 점과 사용자와 상호작용을 한다는 점에서 약간의 차이가 있다.

 

다음 프로그램은 몇 개의 창을 더 만드는  프로그램이다. 마치 여러 개의 창을 초대해 파티를 여는 것 같아서 이름을 ThrowWindowParty로 했다.

using System;
using System.Windows;
using System.Windows.Input;

namespace ThrowWindowParty
{
    public class ThrowWinowParty : Application
    {
        [STAThread]
        public static void Main()
        {
            ThrowWinowParty app = new ThrowWinowParty();
            //app.ShutdownMode = ShutdownMode.OnMainWindowClose;
            app.Run();

        }

        protected override void OnStartup(StartupEventArgs e)
        {
            //메인 창이 닫힐 때만 Run이 반환되고, 프로그램이 종료된다.
            ShutdownMode = ShutdownMode.OnMainWindowClose;

            Window winMain = new Window();
            winMain.Title = "Main Window";
            winMain.MouseDown += WindowOnMouseDown;
            winMain.Show();

            for (int i = 0; i < 2; i++)
            {
                Window win = new Window();
                win.Title = "Extra Window No. " + (i + 1);
                //세 개의 윈도우 모두 화면 하단부에 있는 윈도우의 작업 표시줄에 나타나지 않도록 설정.
                win.ShowInTaskbar = false;
                //MainWindow = win;
                win.Owner = winMain;
                win.Show();
            }
        }

        private void WindowOnMouseDown(object sender, MouseButtonEventArgs e)
        {
            Window win = new Window();
            win.Title = "Modal Dialog Box";
            win.ShowDialog();
        }
    }
}

ThrowWindowParty.zip
0.02MB

반응형
반응형

프로그램에서 Application 클래스를 상속받아 프로그램 종료 시 프로그램 종료 여부를 확인하는 팝업 창을 보여주는 예제인 듯 하다.

제공된 예제를 실행했으나, 오버라이딩한 OnSessionEnding 메소드가 호출되지 못하고 있다.

내가 잘못 알고 있는 것일 수도 있는데..혹 OnSessionEnding 메소드가 호출되기 위한 조건이나 방법을 아시는 분이 있으시면 댓글로 알려 주셨으면 합니다.

제가 책을 읽으며 테스트 했던 소스는 아래와 같습니다.

using System;
using System.Windows;
using System.Windows.Input;

namespace InheritTheApp
{
    public class InheritTheApp : Application
    {
        [STAThread]
        public static void Main()
        {
            InheritTheApp app = new InheritTheApp();
            app.Run();
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Window win = new Window();
            win.Title = "Inherit the App";
            win.Show();
        }

        protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
        {
            base.OnSessionEnding(e);

            MessageBoxResult result = MessageBox.Show("Do you want to save your data?", 
            	MainWindow.Title, MessageBoxButton.YesNoCancel, MessageBoxImage.Question, 
                MessageBoxResult.Yes);

            e.Cancel = (result == MessageBoxResult.Cancel);
        }

        protected override void OnExit(ExitEventArgs e)
        {
            MessageBox.Show("Application이 종료됩니다.");
            base.OnExit(e);
        }
    }
}

InheritTheApp.zip
0.01MB

반응형
반응형

사실상 프로그램이 하는 일은 이벤트(event)에 대해 반응하는 것이 전부라고 말할 수 있다. 이벤트란 통상적으로 사용자의 키보드, 마우스, 스타일러스 펜의 입력을 의미한다. UIElement 클래스에는 키보드, 마우스, 스타일러스와 관련된 몇 가지의 이벤트가 정의돼 있으며, Window 클래스는 이 모든 이벤트를 상속받는다. 이런 이벤트 중 하나는 MouseDown 이다. 사용자가 윈도우의 클라이언트 영역을 누를 때마다 윈도우에서는 MouseDown 이벤트가 발생한다.

 

사용자가 윈도우 클라이언트 영역을 누를 때마다 MouseDown 이벤트가 발생된다. 이벤트 핸들러의 첫 번째 인자는 이벤트를 발생시키는 객체인데, 여기서는 Window 객체가 된다. 이벤트 핸들러는 이 객체를 Window 타입의 객체로 안전하게 형 변환한다.

 

이 프로그램에서 이벤트 핸들러에 Window 객체가 필요한 이유는 두 가지다. 첫 번째 이유는 MouseButtonEventArgs 클래스에 정의된 GetPosition 메소드의 인자로 Window 객체를 넘겨야 하기 때문이다. 이 GetPosition 메소드는 Point 타입(System.Windows에 정의된 구조체)의 객체를 반환하는데, 이 값은 인자로 넘긴 객체의 좌측 상단을 기준으로 한 마우스의 위치 좌표다. 두 번째 이유는 이벤트 핸들러가 Window 객체의 Title 프로퍼티를 읽어서 메시지 박스의 제목으로 사용하기 때문이다.

 

[HandleAnEvent.cs 파일]

using System;
using System.Windows;
using System.Windows.Input;

namespace HandleAnEvent
{
    public class HandleAnEvent
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();

            Window win = new Window();
            win.Title = "Handle An Event";
            win.MouseDown += WindowOnMouseDown;

            app.Run(win);
        }

        private static void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            Window win = sender as Window;
            //Window win = Application.Current.MainWindow;
            string strMessage = string.Format("Window clicked with {0} button at point({1})", args.ChangedButton, args.GetPosition(win));

            MessageBox.Show(strMessage, win.Title);
            //MessageBox.Show(strMessage, Application.Current.MainWindow.Title);
        }
    }
}

 

프로젝트 다운로드

HandleAnEvent.zip
0.02MB

반응형

+ Recent posts