MSDN : http://msdn2.microsoft.com/en-us/library/ms743714.aspx

Application Management Overview

이 토픽은 Application 클래스를 소개하는 것으로 시작해 Application에 의해 제공되는 애플리케이션, 애플리케이션의 라이프타임 및 부가 서비스를 어떻게 정의하는가와 같은 서비스의 개요를 제공합니다.

이 토픽은 다음 섹션과 같은 내용을 담고 있습니다. 애플리케이션 클래스 The Application Class

WPF에서, 애플리케이션은 Application 클래스로 캡슐화됩니다. Application은 다음과 같은 기능의 서비스를 제공합니다.
  • 공통 애플리케이션 기반(infrastructure)을 생성하고 관리
  • 애플리케이션 라이프타임에 상호 작용하고 추적
  • 커맨드 라인 파라미터를 받고 처리
  • 애플리케이션 스코프 속성과 리소스를 공유
  • 핸들되지 않은 예외를 검출하고 반응
  • 종료 코드를 반환
  • 독립 애플리케이션들의 윈도들을 관리(MSDN : WPF Windows Overview 참고)
  • XAML 브라우저 애플리케이션(XBAPs)에서의 내비게이션 및 내비게이션 윈도와 프레임을 가진 독립 애플리케이션의 추적(MSDN : Navigation Overview 참고)

애플리케이션 구현

일반적인 WPF 애플리케이션은 마크업과 코드-비하인드 모두를 사용하여 정의됩니다. 이것은 마크업을 사용하여 선언적으로 애플리케이션 속성, 리소스 및 이벤트 등록을 설정할 수 있게 하고, 이벤트를 처리할 때 코드-비하인드에서 특정한 동작을 구현합니다. 다음 예제는 어떻게 마크업과 코드-비하인드를 모두 사용하여 애플리케이션을 정의하는지를 보여줍니다.

XAML

<Application

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    x:Class="App" />

C#
using System.Windows;
public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }
}

마크업 파일과 코드-비하인드 파일을 함께 사용하기 위해서 다음의 사항이 필요합니다.

  • 마크업에서, Application 엘리먼트는 반드시 x:Class 어트리뷰트에 의해 정의되는 이름으로 프로젝트가 빌드될 때 마크업 파일을 위해 partial class를 만들기 위한 MSBuild를 구성하는 x:Class 어트리뷰트를 포함해야 합니다. 이것은 XAML 스키마(xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml")를 위한 XML 네임스페이스 선언의 추가를 요구합니다. 부분적으로 생성된 partial class는 이벤트 등록과 마크업에서 구현된 프로퍼티의 설정을 위해 호출되는 InitializeComponent를 구현합니다.
  • 코드-비하인드에서, 클래스는 반드시 마크업에서 x:Class 어트리뷰트로 지정된 partial class와 같은 이름이어야 하고, Application을 상속할 필요가 있습니다. 이는 코드-비하인드 파일이 빌드될 때 마크업 파일을 위해 생성된 partial class와 연결되는 것을 가능케합니다(WPF 애플리케이션 빌드하기 참고).
  • 코드-비하인드에서, 클래스는 반드시 마크업에서 x:Class로 설정된 같은 이름의 partial class로 정의되어야 합니다. 이것은 코드-비하인드 파일이 프로젝트가 빌드될 때 마크업 파일을 위해 생성된 partial class와 연결되는 것을 가능케 합니다(WPF 애플리케이션 빌드하기 참고).
노트:
Microsoft Visual Studio를 사용하여 새 Windows Application(WPF)나 XAML 브라우저 애플리케이션(WPF)프로젝트를 생성할 때, 애플리케이션 정의는 기본적으로 마크업과 코드-비하인드를 모두 포함합니다.

이 최소한의 애플리케이션 정의는 WPF 애플리케이션 작업으로 생성하기 위해 작성할 필요가 있는 코드의 전부입니다. 그러나, 애플리케이션 정의는 특정한 방법의 MSBuild를 위해 설정될 필요가 있습니다.

MSBuild를 위한 애플리케이션 정의 설정

모든 WPF 실행 애플리케이션(독립적인 애플리케이션과 XBAP)은 실행하기 위한 기반(infrastructure)의 어떤 레벨의 구현이 필요합니다. 먼저, 이것은 애플리케이션을 시작시키기 위해 OS가 호출하는 함수로 유명한 엔트리 포인트 함수를 포함합니다. 전통적으로 개발자는 전부는 아니더라도 그것을 위한 코드의 어느 정도를 작성해야 했습니다. 그러나, WPF는 MSBuild ApplicationDefinition 아이템과 같은 애플리케이션 정의 마크업 파일을 설정하는 것에 의해 이 코드를 생성할 것입니다. 필요한 설정은 다음 예제에서 보여줍니다. (※역주 : 다음의 코드는 VS2005의 프로젝트 파일(.csproj또는 .vbproj)를 텍스트 편집기에서 열어 확인할 수 있습니다. 물론 일반적인 경우 이 코드를 직접 수정하는 경우는 없습니다.)

<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<ApplicationDefinition Include="App.xaml" />
<Compile Include="App.xaml.cs" />
...
</Project>

여기에서, 코드-비하인드 파일은 MSBuild의 Compile 아이템에 의해 설정됩니다. 또한, 코드-비하인드 파일은 추가적인 언어 정의 접미어(.cs.vb)가 붙은 마크업 파일과 같은 이름을 가지고 있습니다. 이 접미어는 Microsoft Visual Studio가 기본적으로 이 규칙을 사용하긴 하지만 반드시 필요한 것은 아닙니다.

노트:
WPF 애플리케이션 작성의 자세한 사항은, WPF 애플리케이션 만들기를 참조합니다.

애플리케이션 정의와 MSBuild 설정과의 조합의 효과는 MSBuild가 다음과 같은 코드를 생성하게 합니다.

C#
public class App : Application
{
    public App() { }
    [STAThread]
    public static void Main()
    {
        App app = new App();
        app.InitializeComponent();
        app.Run();
    }

    public void InitializeComponent()
    {
        // Register XAML-declared events
        ...
        // Set XAML-declared properties
        ...
    }
}

이 애플리케이션이 시작되었을 때, 윈도는 엔트리 포인트 함수(C#과 Visual Basic 모두 Main)를 호출할 것입니다. 이후, 엔트리 포인트 함수는 이벤트 등록과 마크업에서 구현된 속성 설정을 위한 InitializeComponent를 호출하기 전에 사용자 애플리케이션 클래스의 새 인스턴스를 생성합니다.

거의 대부분, AppDomain별로 단 하나의 Application 클래스나 서브클래스의 인스턴스만이 존재합니다. 이 때문에, 애플리케이션-스코프 속성과 리소스(나중에 다룹니다)의 단일 셋으로의 공유 접근을 지원하기 위해, Application은 싱글톤 패턴을 사용하여 구현됩니다. 싱글톤 패턴은 싱글톤(C#에서 싱글톤 구현하기 참고)이라고 알려진 단 하나의 인스턴스만을 가지는 클래스 생성을 위한 모델입니다. 싱글톤 클래스는 static 속성으로 공유 접근을 제공하는 자신의 인스턴스를 만듭니다. Application 클래스를 위한 이 속성은 다음과 같은 Current입니다.

C#
// Get reference to application
App currentApp = (App)Application.Current;

생성된 코드에서, App가 인스턴스화된 이후 호출되는 Run 메소드를 알 수 있을 것입니다. 이것은 WPF 애플리케이션의 생명이 시작된다는 것을 말합니다.

노트:
실행 애플리케이션의 단 하나의 인스턴스가 실행될 것을 검출할 필요가 있을 때를 포함하여, 이 코드를 직접 작성할 필요가 있는 상황이 있습니다. 더 자세한 정보는 단일 인스턴스 검출 샘플을 참고합니다.

애플리케이션 라이프타임

System.Windows.Application.Run이 호출된 후, 애플리케이션이 시작되고, 라이프타임 동안 사용자나 프로그램 조건에 응답하여 최종적으로 실행을 중지하기 전까지 여러번 비활성화와 활성화할 것입니다.

애플리케이션 시작하기
System.Windows.Application.Run
이 호출된 후, Application은 모든 애플리케이션에서 공통적으로 필요한 기반의 셋을 초기화합니다. 기반이 구축될 때, Application은 WPF 애플리케이션이 시작되는 순간을 의미하는 Startup 이벤트를 발생시킵니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    Startup="App_Startup" />
C#
public partial class App : Application
{
   
void App_Startup(object sender, StartupEventArgs e)
    {
       
// Application is running
    }
}

MSBuild ApplicationDefinition 아이템과 같은 애플리케이션 정의를 구현할 때 시작(launching), 실행(running) 및 애플리케이션 기반의 초기화(establishing) 작업이 WPF에 의해 작동됩니다. 이것은 대부분 애플리케이션의 시작을 위해 항상 필요한 UI 보여주기와 커맨드라인 매개 변수 처리를 포함하는 기능 구축에 집중할 수 있게 합니다.

유저 인터페이스 보여주기
대부분의 윈도 애플리케이션은 유저 인터페이스를 열기 때문에 실행을 시작할 때 Startup 이벤트 핸들러는 그것을 수행하기에 적합한 위치입니다. 독립적인 애플리케이션을 위해, 이것은 다음과 같이 윈도를 보여주는것에 관계됩니다.

C#
public partial class App : Application
{
    void App_Startup(object sender, StartupEventArgs e)
    {
        // Application is running

        // Show the main window
        MainWindow mainWindow = new MainWindow();
        mainWindow.Show();
    }
}

단지 Startup을 처리하는 것이 윈도를 보여주기 위한 것이라면, 대신에 마크업에서 StartupUri를 설정할 수 있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="MainWindow.xaml" />

독립 애플리케이션의 UI가 윈도 대신에 페이지(Page)의 조합일 경우에도, StartupUri를 시작 페이지로 설정하는데 사용할 수 있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="HomePage.xaml" />

XBAP 애플리케이션에서도, StartupUri을 사용하여 윈도 Internet Explorer에서 보여줄 첫번째 페이지를 지정할 수 있습니다.

UI를 보여주는 것에 관하여 StartupUri를 세팅하는 대신 Startup처리가 필요가 있는 주 원인은 기본 생성자를 사용하지 않거나 UI를 보여주기 전에 속성을 설정하는 것을 구현하는 클래스를 인스턴스화하기 위해서 입니다.

애플리케이션에서 커맨드라인 매개 변수를 받아서 처리하기 위해서도 Startup을 처리할 필요가 있을 것입니다.

커맨드라인 매개 변수 처리하기
윈도에서, 독립 애플리케이션은 커맨드 프롬프트나 데스크탑에서 시작될 수 있습니다. 두 경우 모두, 커맨드라인 매개 변수를 다음과 같은 문법을 사용하여 애플리케이션에 전달할 수 있습니다.

wpfapplication.exe /winstate:maximized

애플리케이션이 초기화하는 동안, WPF는 OS로부터 커맨드라인 매개 변수를 받고 그것을 StartupEventArgs 파라미터의 Args 프로퍼티를 통해 Startup 이벤트 핸들러에 전달합니다. 다음과 같은 코드를 사용하여 커맨드라인 매개 변수를 받아 저장할 수 있습니다. (※역주 : 다음 코드는 원문에서 XAML과 C#으로 나뉘어 있지 않고 XAML이라고만 표시되어 있는데 내용상 C#으로 분리해야 맞다고 생각됩니다. 또한 이후에도 두세번 이런 코드가 있는데 모두 XAML과 C#으로 분리하였습니다.)

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="MainWindow.xaml"
    Startup="App_Startup" />
C#

using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Windows;

public partial class App : Application

{

    // Indexed command line args using hash table

    public static Hashtable CommandLineArgs = new Hashtable();


    void App_Startup(object sender, StartupEventArgs e)

    {

        // Don't bother if no command line args were passed

        // NOTE: e.Args is never null - if no command line args were passed,

        //       the length of e.Args is 0.

        if (e.Args.Length == 0) return;


        // Parse command line args for args in the following format:

        //   /argname:argvalue /argname:argvalue /argname:argvalue ...

        //

        // Note: This sample uses regular expressions to parse the command line arguments.

        // For regular expressions, see:

        // http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconRegularExpressionsLanguageElements.asp

        string pattern = @"(?<argname>/\w+):(?<argvalue>\w+)";

        foreach (string arg in e.Args)

        {

        Match match = Regex.Match(arg, pattern);


        // If match not found, command line args are improperly formed.

        if (!match.Success) throw new ArgumentException("The command line arguments are improperly formed. Use /argname:argvalue.");


        // Store command line arg and value

        CommandLineArgs[match.Groups["argname"].Value] = match.Groups["argvalue"].Value;

    }

}

 

노트:
자세한 정보는 커맨드라인 매개 변수 처리하기 샘플을 참고합니다.

애플리케이션 활성화와 비활성화
애플리케이션의 라이프타임 동안, 사용자는 그것과 현재 실행중인 다른 애플리케이션 사이의 전환을 할 것입니다. 사용자가 다른 애플리케이션의 윈도 중 하나를 활성화하여 전환하는 시점에 현재 애플리케이션은 비활성화됩니다. 이 상황은 Deactivated를 처리하여 검출할 수 있습니다. 반대로, 사용자가 다시 애플리케이션의 윈도 중 하나를 선택하면, 애플리케이션은 활성화되고 따라서, Activated가 발생됩니다. ActivatedDeactivated 모두 다음과 같이 처리될 수 있습니다.

XAML
<Application
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="App"
  StartupUri="MainWindow.xaml"
  Activated="App_Activated"
  Deactivated="App_Deactivated" />
C#
using System;

using System.Windows;

public partial class App : Application

{

    bool isApplicationActive;


    void App_Activated(object sender, EventArgs e)

    {

        // Activated

        this.isApplicationActive = true;

    }


    void App_Deactivated(object sender, EventArgs e)

    {

        // Deactivated

        this.isApplicationActive = false;

    }

}

각 윈도 별로 활성화와 비활성화를 처리할 필요가 있다면, 전체 애플리케이션 대신, System.Windows.Window.ActivatedSystem.Windows.Window.Deactivated를 처리할 수 있습니다.

처리되지 않은 예외
애플리케이션이 실행되고 있을 때, 애플리케이션 코드는 예상치 못한 잠재적으로 처리되지 않은 예외를 던질 수 있습니다. 기본적으로 .NET Framework 3.0은 애플리케이션이 다운되기 전에 다음 그림과 같은 알림을 사용자에게 보여주는 것으로 처리되지 않은 예외에 응답합니다.

사용자 삽입 이미지

유저 경험의 관점에서, 애플리케이션이 다음 항목의 일부 혹은 전부를 수행하여 기본 동작을 피하는 것이 더 낫습니다.

  • 처리되지 않은 예외를 검출하기 위한 공통적인 메카니즘을 제공.
  • 사용자에게 더욱 설명적인 정보를 제공.
  • 애플리케이션이 계속 실행되도록 시도.
  • 일반적으로 윈도 이벤트 로그에 설명적인 정보를 로깅.

이 지원을 구현하는 것은 다음과 같이 DispatcherUnhandledException이 발생하여 처리되지 않은 예외를 검출할 수 있게 되는 것에 달려있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="MainWindow.xaml"
    DispatcherUnhandledException="App_DispatcherUnhandledException" />
C#
public partial class App : Application

{

    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)

    {

        // Process unhandled exception

        ...

        // Prevent default unhandled exception processing

        e.Handled = true;

    }

}

DispatcherUnhandledException 이벤트 핸들러는 예외 자신(System.Windows.Threading.DispatcherUnhandledExceptionEventArgs.Exception)을 포함하여 처리되지 않은 예외에 관한 컨텍스트 정보를 담고있는 DispatcherUnhandledExceptionEventArgs 파라미터로 전달됩니다. 이 정보를 사용하여 예외가 복구가능한지 아닌지를 결정할 수 있습니다. 복구 가능한 예외의 예를 들자면 FileNotFoundException이 있고, 복구 불가능한 예외의 예는 StackOverflowException가 있습니다.

언제든 DispatcherUnhandledExecption을 처리할 때는, 반드시 System.Windows.Threading.DispatcherUnhandledExceptionEventArgs.Handled 프로퍼티를 true(※역주 : MSDN에는 false로 나와있는데 문맥상 true가 맞다고 생각됩니다.)로 설정해야 합니다. 그렇지 않으면, WPF는 여전히 예외가 처리되지 않았다고 생각하여 기본 동작으로 애플리케이션을 종료합니다.

노트:
처리되지 않은 예외가 발생하였고 DispatcherUnhandledException 이벤트가 처리되지 않거나 이벤트가 Handledfalse로 설정하여 처리되었다면, 애플리케이션은 곧바로 종료될 것입니다. 게다가, Application에 의해 정의된 어떤 이벤트도 발생하지 않습니다. 따라서, 애플리케이션이 애플리케이션의 종료 시점에 실행할 필요가 있는 코드를 가졌다면 DispatcherUnhandledException을 처리할 필요가 있을 것입니다.

상세한 내용은 DispatcherUnhandledExecption 처리하는 것을 보여주는 Unhandled Application Exceptions Sample을 참고합니다.

애플리케이션 종료(Shutdown)
처리되지 않은 예외가 일어났을 때 예외가 여전히 처리되지 않았다면 애플리케이션이 종료될 것입니다. 애플리케이션은 아마도 다음과 같은 경우로 종료되는 경우가 더 많을 것입니다.

  • 사용자에 의해 모든 윈도가 닫혔을 때.
  • 사용자에 의해 메인 윈도가 닫혔을 때.
  • 사용자가 로그 오프나 윈도 종료로 윈도 세션을 끝낼 때.
  • 종료를 의미하는 조건을 만났을 때.

이 모든 경우에, Shutdown메소드가 호출됩니다. Shutdown이 코드에서 호출되는지 WPF에서 호출되는지는 Application 설정을 어떻게 하느냐에 달려있습니다.

종료(Shutdown) 모드
일반적으로, 독립 애플리케이션의 라이프타임은 그것이 보여주는 윈도의 라이프타임을 캡슐화 합니다. 애플리케이션의 종류에따라, 애플리케이션은 모든 윈도가 닫히거나 메인 윈도가 닫혔을 때 종료될 것입니다. 이 두가지 시나리오는 가장 일반적이기 때문에, ShutdownMode를 다음의 ShutdownMode 열거값 중 하나로 설정할 때 Application을 자동으로 종료하도록 설정할 수 있습니다.

예를 들어, 애플리케이션이 메인 윈도가 닫혔을 때 종료되도록 설정하고 싶다면 다음과 같이 하면 됩니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    ShutdownMode="OnMainWindowClose" />
노트:
메인 윈도는 System.Windows.Application.MainWindow 프로퍼티에 의해 참조되는 윈도입니다. 기본적으로 이 프로퍼티의 값은 인스턴스화 된 애플리케이션의 첫번째 윈도를 참조하지만 이 값은 나중에 프로그램에서 변경할 수 있습니다.

ShutdownMode를 설정하는 것은 언제, 누구에 의해 Shutdown이 호출되는지를 명시합니다. ShutdownMode가 OnLastWindowClose나 OnMainWindowClose로 설정한 경우, WPF는 이 열거값 설정에의해 지정된 조건이 특정되었을 때 자동으로 Shutdown 메소드를 호출합니다.

ShutdownModeOnExplicitShutdown으로 설정되었다면, Shutdown을 호출하는 것은 개발자의 책임이고, 그렇지 않을 경우 애플리케이션은 모든 윈도가 닫힌다고 해도 계속 실행될 것입니다.

세션 종료(Ending)
ShutdownMode를 세팅하는 것은 애플리케이션 종료(shutting down)을 위한 내부 메커니즘이며, 애플리케이션은 또한 다음과 같은 외부 조건에 의해 종료될 수 있습니다.
  • 사용자가 윈도를 로그 오프하여 세션이 종료될 때.
  • 사용자가 윈도를 종료하거나 재시작하거나 하이버네이션하여 세션이 종료될 때.

사용자가 세션을 종료할 때, 윈도는 현재 동작중인 각 애플리케이션을 위해 언제 그랬는지 검출하고, 필요하다면 세션이 종료되는 것을 막도록 기회를 줍니다. 사용자가 데이터를 편집할 수 있는 (워드 프로세서나 스프레드 시트와 같은)애플리케이션은 이 기능을 사용하기에 가장 적합합니다. 사용자는 실수로 저장하지 않은 문서를 닫도록 시도할 수도 있고, 예기치 못하게 애플리케이션에 저장하지 않은 문서를 둔 채로 윈도를 종료할 수도 있습니다. 따라서, 애플리케이션은 애플리케이션 데이터가 저장되었는지를 확인할 기회를 사용자에게 줄 수 있고, 아니면 사용자에게 윈도의 종료를 막을 기회를 줄 수 있습니다.

Application은 언제 윈도가 세션 종료 알림을 발생시키는지, SessionEnding 이벤트가 언제 일어났는지를 검출합니다. SessionEnding을 처리하여 다음과 같이 검출하고, 응답하고, 세션 종료를 취소할 수 있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    SessionEnding="App_SessionEnding" />
C#

public partial class App : Application

{

    void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)

    {

        using (StreamWriter writer = File.AppendText("output.txt"))

        //using (FileStream stream = File.AppendText("output.txt"))

        //using (StreamWriter writer = new StreamWriter(stream))

        {

            writer.WriteLine("OnSessionEnding");

        }


        // Ask the user if they want the session to end

        string msg = "The application is shutting down for the following reason: " + e.ReasonSessionEnding + "\n\nShutdown?";

        string title = "An Application";

        MessageBoxButton buttons = MessageBoxButton.YesNo;

        MessageBoxImage icon = MessageBoxImage.Stop;

        MessageBoxResult result = MessageBox.Show(msg, title, buttons, icon);


        // If they don't, prevent both the session from ending and the

        // application from shutting down

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

    }

}



SessionEnding 이벤트 핸들러에게 전달된 SessionEndingCancelEventArgs 파라미터는 ReasonSessionEnding 속성을 통해 세션 종료의 원인을 노출하고, 세션 종료를 취소할 수 있는 Cancel 속성을 구현합니다.

종료(Exit)
애플리케이션에 의해 - 처리되지 않은 예외나 사용자 세션 종료에 의한 종료가 아닌 - 종료(shutdown)가 시작되었다면 애플리케이션의 라이프타임은 끝이 날 것입니다. 종료하기 전, 애플리케이션은 애플리케이션의 상태를 보관하는 것과 같은 최종 처리 동작을 필요로 할 것입니다. 이 경우, Exit 이벤트를 처리할 수 있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="MainWindow.xaml"
    Startup="App_Startup"
    Exit="App_Exit" />


C#

using System;

using System.Windows;

using System.IO;

using System.IO.IsolatedStorage;

public partial class App : Application

{

    string filename = "App.txt";

    void App_Exit(object sender, ExitEventArgs e)

    {

        // Persist application-scope property to isolated storage

        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();

        using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Create, storage))

        using (StreamWriter writer = new StreamWriter(stream))

        {

            // Persist each application-scope property individually

            foreach (string key in this.Properties.Keys)

            {

                writer.WriteLine("{0},{1}", key, this.Properties[key]);

            }

        }

    }

}


종료 코드(Exit Code)
애플리케이션은 사용자 요청에 응답한 OS에 의해 가장 많이 시작됩니다. 그러나, 애플리케이션은 어떤 특정한 작업을 수행하기 위하여 다른 애플리케이션으로부터 시작될 수 있습니다. 이 경우, 호출하는 쪽과 호출받은 애플리케이션은 분리된 프로세스에서 동작합니다. 이런 상황에서 호출한 애플리케이션의 실행은 호출받은 애플리케이션이 어떻게 종료되었냐에 달려있습니다. 이 상황에서, 호출받은 애플리케이션은 exit code로 알려진 특수한 정수 코드를 사용함으로서 어떻게 종료되었는지를 알리는 값을 반환할 수 있습니다. 기본적으로, Application0의 값을 반환할 것입니다. 이 값을 변경하기 위해, exit code가 될 정수 매개 변수를 받아들이도록 오버로드된 Shutdown을 호출할 수 있습니다.

C#
// Shutdown and return a custom exit code
Application.Current.Shutdown(-1);


Exit 이벤트를 처리하여 exit code의 값을 검출하고 변경할 수 있습니다. Exit 이벤트 핸들러는 ApplicationExitCode 속성으로 exit code에의 접근을 제공하는 ExitEventArgs를 전달합니다. 자세한 정보는 Exit를 참고합니다.

애플리케이션 라이프타임 이벤트
다음 그림은 애플리케이션의 라이프타임에서 중요한 이벤트와 그것이 발생하는 순서를 표현합니다.
사용자 삽입 이미지

다른 애플리케이션 서비스

이 토픽은 Application에 의해 나타나는 애플리케이션의 핵심 라이프타임을 다룹니다. 그러나, 애플리케이션은 다음을 포함하는 더욱 자세하게 논의될 또 다른 서비스를 제공합니다.
  • 애플리케이션과 윈도 관리.
  • 애플리케이션-스코프 속성.
  • 애플리케이션-스코프 리소스.
  • 애플리케이션과 내비게이션 관리.

애플리케이션과 윈도
ApplicationWindow는 가까운 관계에 있습니다. 앞서 살펴본 것처럼, 애플리케이션의 라이프타임은 ShutdownMode 속성으로 지정되는 윈도의 라이프타임에 달려있다고 할 수 있습니다. 애플리케이션은 어떤 윈도가 메인 애플리케이션 윈도(System.Windows.Application.MainWindow)로 지정되었는지 기록하고, 현재 인스턴스화 된 윈도(System.Windows.Application.Windows)의 목록을 관리합니다.

더욱 자세한 정보는 WPF Windows Overview를 참고합니다.

애플리케이션 스코프 속성
애플리케이션은 애플리케이션 영역을 넘어 공유할 수 있는 상태를 노출하기 위한 Properties 속성을 구현합니다. 다음은 Properties를 사용하는 예제를 제공합니다.

C#
  // Set an application-scope property with a custom type
  CustomType customType = new CustomType();
  Application.Current.Properties["CustomType"] = customType;
...
  // Get an application-scope property
  // NOTE: Need to convert since Application.Properties is a dictionary of System.Object
  CustomType customType = (CustomType)Application.Current.Properties["CustomType"];

자세한 정보는 다음을 참고합니다.

애플리케이션-스코프 리소스
애플리케이션은 개발자가 애플리케이션간 유저 인터페이스(UI) 리소스를 공유할 수 있게 하는 Resources 속성을 구현합니다. 다음은 Resources(※역주 : 원문에는 Properties라고 되어 있지만, 오류라고 생각됩니다.)를 사용하는 예제를 제공합니다.

C#
  // Set an application-scope resource
  Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;
...
  // Get an application-scope resource Brush whiteBrush = (Brush)Application.Current.Resources["ApplicationScopeResource"];

자세한 정보는 다음을 참고합니다.

애플리케이션과 내비게이션
내비게이션을 가진 독립적인 애플리케이션을 위해, NavigationWindow과 Frame이나 Application이 검출하는 애플리케이션내의 내비게이션과 다음과 같은 적절한 이벤트를 사용합니다.

자세한 정보는 Navigation Overview를 참고합니다.

애플리케이션과 애플리케이션 데이터 파일
WPF 애플리케이션은 리소스 데이터 파일, 컨텐트 데이터 파일 및 원격 데이터 파일을 포함한 몇 가지 데이터 파일의 종류를 관리할 수 있습니다. 다음 헬퍼 메소드는 이 데이터 파일의 종류를 로드하는데 사용할 수 있습니다.

참고

레퍼런스
Application
컨셉
WPF Windows Overview
Navigation Overview
WPF Data Files

신고
Posted by gongdo


티스토리 툴바