'WPF 설치'에 해당되는 글 1건

  1. 2007/11/18 찰스 페졸드 - WPF 정리.!

찰스 페졸드 - WPF 정리.!

C# 2007/11/18 23:17 posted by isili

순수하게 공부용입니다.

1. Application 과 Window.

간단한 소스와 함께 시작되었습니다.

26P 에 보시면.
"WPF 프로그램에서는 [STAThread] 속성이 반드시 Main 앞에 나와야 한다." 
라는 부분이 있는데...

그렇지 않으면 InvalidOperationException 예외 상황과 함께 프로그램이 종료 된다고 ...

친절하게도 위의 속성은 단일 쓰레드 아파트먼트로 지정하는 것을 의미 한다고 적혀있습니다.

여기에서 질문! 단일 쓰레드 아파트먼트?
구글에 물어보았습니다.. 역시나 MSDN!?

Using single-threaded apartments (the apartment model process) offers a message-based paradigm for dealing with multiple objects running concurrently.
싱글 쓰레드 아파트먼트를 사용한다는 것은 멀티플 오브젝트를 동시에 다루기 위한 메시지 기반의 패러다임을 제시한다.

  It enables you to write more efficient code by allowing a thread, while it waits for some time-consuming operation to complete, to allow another thread to be executed.
그것은 너가 효율적인 코드를 하나의 쓰레드에서 작성할수 있도록 한다.  하나의 작동이 끝난다면 다른 쓰레드가 실행될 수 있도록 허가한다.

Each thread in a process that is initialized as an apartment model process, and that retrieves and dispatches window messages, is a single-threaded apartment thread.
한 프로세스에서 각 쓰레드는 하나의 아파트 모델 프로세스에 의해 초기화 되고 되찾고, 윈도우 메시지에 의해 처리된다. 싱글쓰레드 아파트 먼트이다. (개판)

Each thread lives within its own apartment
각각의 쓰레드는 자신의 아파트 먼트를 가진다.

Within an apartment, interface pointers can be passed without marshaling, and therefore, all objects in one single-threaded apartment thread communicate directly.
하나의 아파트먼트 안에서 인터페이스 포인터는 마샬링 없이 통과될수 있다 따라서 모든 오브젝트는 하나의 쓰레드 안에서 직접적으로 통신할 수 있다.

A logical grouping of related objects that all execute on the same thread, and therefore must have synchronous execution, could live on the same single-threaded apartment thread.
논리적으로 그루핑된 오브젝트는 하나의 쓰레드에서 실행된다 따라서 동기적으로 실행되어여 하고 같은 싱글쓰레드 아파트먼트에서 존재해야 한다.(역시 개판)

an apartment model object cannot reside on more than one thread.
하나의 아파트 모델 오브젝트는 다른 쓰레드에 존재할 수 없다.

Calls to objects in other processes must be made within the context of the owning process, so distributed COM switches threads for you automatically when you call on a proxy.

http://www.codeproject.com/com/CCOMThread.asp (참고자료)

머 저정도로 설명하고, 사실 책에는

어플리케이션이 다중 쓰레드를 사용하지 않는다는 것을 의미한다고 간단하게 설명하였음.

첫번째 기초프로그램을 제작하기 전에 반드시 해야할 것이 있다면..

27P 3번 PresentationCore , PresentationFramework, System, WindowBase를 반드시 포함.

VS2005를 켜고 C# WPF Template 를 찾아보았으나 존재하지 않음.
이곳 저곳 찾아보다가..

"먼저 개발을 위한 요구사항은 먼저 .NET 3.0 Framework(http://www.microsoft.com/downloads/details.aspx?familyid=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=ko)를 설치해야 한다. 그리고 2개를 더 설치해줘야 하는데..  Microsoft Windows SDK for .NET Framework 3.0와  Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF)를 순서대로 설치해야 한다. 물론 이 모두에 앞서 OS(Win2000, XP, Vista)와 Visual Studio 2005가 설치되어져 있어야 한다. 참고로 필자의 OS는 .NET 3.0이 이미 설치된 윈도우즈 비스타이다."


위의 준비 사항을 마치면.

직접적으로 WPF 프로그래밍을 시작할 수 있다.

# 이벤트 처리 - 마우스 버튼 클릭 이벤트
[STAThread]
        public static void Main()
        {
            Application app = new Application();
          - 어플리케이션 생성

            Window win = new Window();
            - 윈도우 생성
            win.Title = "Handler An Event";
            win.MouseDown += WindowOnMouseDown;

            app.Run(win);
        }
        static void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            // 이벤트 핸들러의 첫번째 인자는 이벤트를 발생시키는 객체인데, 여기에서는 Window 객체가 된다.
            // 이벤트 핸들러는 이 객체를 Window 타입의 객체로 형 변환한다.
            Window win = sender as Window;

            string strMessage
            = string.Format("Window Click {0}, {1}", args.ChangedButton, args.GetPosition(win));

            MessageBox.Show(strMessage);
        }


 이 프로그램에서 이벤트 핸들러에 Window 객체가 필요한 이유는 두 가지다. 첫 번째 이유는 MouseButtonEventArgs 클래스에 정의된 GetPosition 메소드의 인자로 Window 객체를 넘거야 하기 때문이다. - GetPosition 메소드는 인자로 넘긴 객체의 좌측 상단을 기준으로하는 마우스의 위치를 반환한다.

이 프로그램의 이벤트 핸들러에는 sender 인자를 Window 타입의 객체로 형 변환하고 있지만, 동일한 Window 객체를 이벤트 핸들러 안에서 구하는 방법도 있다.

Main에서 생성된 Window 객체는 정적 필드로 저장돼, 이벤트 핸들러에서 이를 사용할 수 있다.
또 다른 방법으로 Application 클래스의 특정 프로퍼티를 사용해도 된다. (Applicatioin 객체의 Current 프로퍼티)

Application 클래스에는 유용한 몇 가지 이벤트가 정의되어 있는데 이런 이벤트를 처리할 필요가 있다면 Application을 상속하는 클래스를 정의하는 것이다. (오버라이딩을 이용)

# Application 상속을 통한 오버라이딩 구현
# 이벤트 핸들러 관련
class InheritApp : Application
    {
        [STAThread]
        public static void Main()
        {
            InheritApp app = new InheritApp();
            app.Run();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Window win = new Window();
            win.Title = "상속 받은 APP";
            win.Show();
        }

        protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
        {
          // 제대로 호출이 되질 않고 있음.
          // 해당 코드를 Vista에서 재구동해 보겠음
            base.OnSessionEnding(e);
            MessageBoxResult result = MessageBox.Show("Do you want to save your data?", MainWindow.Title,
                MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.Yes);

            // 취소를 누르게 되면 Cancel 플래그를 true 설정하게 되어 종료를 막는다.
            e.Cancel = (result == MessageBoxResult.Cancel);
         
        }
    }

# Application 상속을 통한 오버라이딩 구현
# 부모, 자식 윈도우 관련
  class ThrowWindowParty : Application
    {
        [STAThread]
        public static void Main()
        {
            ThrowWindowParty app = new ThrowWindowParty();
            app.Run();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            //base.OnStartup(e);
            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 = "Ex" + (I + 1);
                win.Show();
            }
        }
        void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            Window win = new Window();
            win.Title = "Modal Dialog Box";
            win.ShowDialog();
        }

    }
// 총 3개의 창이 생성되는데 전부 동등함.
// Application 객체의 MainWindow 프로퍼티를 살펴보면 Show가 호출되는 첫 창이 그 애플리케이션에서 메인 창으로 간주되는 것을 알 수 있다.
// 일반적으로 Run 메소드가 반환될 때 프로그램이 종료되는데 , 마지막 창을 닫을 경우에 Run 메소드가 반환된다. 이와 같은 동작은 Application의 ShutdownMode 프로퍼티를 어떻게 설정하느냐에 따라 다르게 결정.
이 프로퍼티는 ShutdownMode 열거형의 멤버로 설정한다.

기본적으로 ShutdownMode.OnLastWindowClose 멤버가 지정돼있지만 이제 ShutdownMode.OnMainWindowClose로 설정할 경우 Main윈도우가 닫힐 경우 전체 윈도우가 닫힌다.

ShutdownMode에는 OnExplicitShutdown도 포함되어 있는데 Application의 Shutdown 메소드를 명시적으로 호출하는 경우에만 Run이 반환된다.