c#/세미나

[세미나] Blazor / WPF / MAUI 밋업 (Application, Current, MainWindow, GetWindow)

루다대디 2024. 4. 3. 18:56

Application

WPF를 구동시키기 위한 객체인 Application클래스는 메인으로 실행될 Window 생성 시점을 포함하고 있으며,

공용 리소스를 등록할 수 있도록 설계되어 있다

 

OnStartup : 윈도우 생성 시점
internal Class App : Application
{
    [STAThread]
    private static void Main(string[] args)
    {
        Window window = new();
        window.ShowDialog();
    }
}​

 

Run : 애플리케이션 구동
internal Class Starter
{
    [STAThread]
    private static void Main(string[] args)
    {
        _ = new App().Run();
    }
}

 

Application 인스턴스를 생성하고 이를 구동시키는 것은 아주 간단하다

Main과 같은 프로그램 시작점에서 App 인스턴스를 생성하고 Run 메서드를 호출하기만 하면 된다

 


Current

처음 Application 인스턴스를 생성하고 Run 시점에서 Current가 내부적으로 함께 구성된다

Application app1 = Application.Current

 

Current는 Static 맴버이며 Application 타입이다

따라서 형변환을 통해 App으로 사용하는 것도 가능하다

App app2 = Application.Current as App;

 


MainWindow

Current와 같은 맥략으로 OnStartup을 통해 실행된 Window 객체 또한

별도의 지정 없이도 Current.MainWindow를 통해 가져올 수 있다

// 기본 윈도우
Window window1 = Application.Current.MainWindow;
// 특정 UI객체로 형변환
JamesWindow window2 = Application.Current.MainWindow as JamesWindow;

 

따라서 Application과 Window가 이미 기본 설계에 의해 Singleton으로 등록되어 관리되어 있기 때문에

어디서든 Window를 가져올 수 있다

 


GetWindow

그리고 Window를 찾을 수 있는 더 재밌는 방법도 있다

Window window = Window.GetWindow(this);

 

이방법은 

대상 객체를 기준으로 Window 컨트롤이 나올 때 까지

부모 객체를 재귀적으로 찾아 Window 또는 null을 반환하는 기능이다

Application과 Window의 Singleton 인스턴스 계층구조

 

Current / MainWidnow 관리 설계

하지만 이를 ViewModel이나 CustomControl에서 직접적으로 사용하는 것은 좋은방법은 아니다

그 이유는 Application Window의 접근으로 인한 관리 포인트가 늘어나기 때문이다

따라서,

이러한 직접적인 핸들링 작업을 하기 위한 클래스를 아래 예제와 같이 만들어

Singleton 형식으로 관리하여 포인트를 줄이는 것이 현명하다

예제 : AppManager
public class AppManager
{ 
    // app;
    // AddResource
    // Close
    // GetWindow

    private Application app => Application.Current;
    public void AddResource(ResourceDictionary resource)
    {
        app.Resources.MergedDictionaries.Add(resourceDictionary);
    }

    public void Close()
    {
        app.Current.MainWindow.Close();
    }

    public Window GetWindow(UIElement element)
    {
        return Window.GetWindow(element);
    }
}