Share via


アプリケーション管理の概要

このトピックでは、アプリケーションを作成および管理するための Windows Presentation Foundation (WPF) サービスの概要を説明します。 WPF アプリケーションの核は Application クラスで、これがさまざまなコア アプリケーション サービスをサポートしています。 ここでは、最も重要なサービスの概要を説明します。

このトピックは、次のセクションで構成されています。

  • Application クラス
  • アプリケーション定義
  • 現在のアプリケーションの取得
  • アプリケーションの有効期間
  • その他のアプリケーション サービス
  • 関連トピック

Application クラス

アプリケーションは、user interface (UI)、ビジネス ロジック、データ アクセス ロジック、コントロール、データなど、多様なアプリケーション固有の要素で構成されています。 これらの要素は、通常はアプリケーションごとに異なります。 ただし、アプリケーションの実装と管理で共通に使用される機能のセットを共有できることが多々あります。 WPF では、この共通のアプリケーションを対象とする機能が Application クラスでカプセル化されており、次のサービスを提供します。

  • 共通アプリケーション インフラストラクチャを作成し、管理する。

  • アプリケーションの有効期間を追跡し、これと対話する。

  • コマンド ライン パラメーターを取得し、処理する。

  • アプリケーション スコープのプロパティとリソースを共有する。

  • 未処理の例外を検出し、これに応答する。

  • 終了コードを返す。

  • スタンドアロン アプリケーションのウィンドウを管理する (「WPF ウィンドウの概要」を参照)。

  • ナビゲーションを追跡し、管理する (「ナビゲーションの概要」を参照)。

アプリケーションでこれらのサービスを使用するには、Application クラスを使用して、アプリケーション定義を実装する必要があります。

アプリケーション定義

WPF アプリケーション定義は Application の派生クラスで、特別な Microsoft build engine (MSBuild) 設定を使用して構成します。

アプリケーション定義の実装

一般的な WPF アプリケーション定義は、マークアップと分離コードの両方を使用して実装します。 そのため、マークアップを使用して、アプリケーションのプロパティやリソースの設定、イベントの登録を宣言したり、分離コードを使用して、イベントの処理やアプリケーション固有の動作を実装したりすることができます。

マークアップと分離コードの両方を使用してアプリケーション定義を実装する方法を次の例に示します。

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SDKSample.App" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace
using System.Windows;  // Application

namespace SDKSample
{
    public partial class App : Application { }
}

マークアップ ファイルと分離コード ファイルを連携させるには、次のようにする必要があります。

  • マークアップの Application 要素に、x:Class 属性を含める必要があります。 アプリケーションのビルド時にマークアップ ファイルに x:Class が含まれていると、MSBuild は、x:Class 属性で指定された名前を持つ、Application から派生した partial クラスを作成します。 このためには、XAML スキーマ (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml") に XML 名前空間宣言を追加する必要があります。

  • 分離コードでは、クラスは、マークアップ内の x:Class 属性で指定されている名前を持つ partial クラスでなければなりません。また、Application から派生する必要があります。 これにより、分離コード ファイルと、アプリケーションのビルド時にマークアップ ファイル用に生成される partial クラスとが関連付けられます (「WPF アプリケーション (WPF) のビルド」を参照)。

メモメモ

Microsoft Visual Studio を使用して WPF アプリケーション プロジェクトまたは WPF ブラウザー アプリケーション プロジェクトを新しく作成すると、アプリケーション定義が既定で含まれ、マークアップと分離コードの両方を使用して定義されます。

このコードは、アプリケーション定義を実装するために最低限必要です。 ただし、アプリケーションをビルドして実装する前に、追加の MSBuild 構成をアプリケーション定義に対して行う必要があります。

MSBuild 用のアプリケーション定義の構成

スタンドアロン アプリケーションや XAML browser applications (XBAPs) を実行できるようにするには、一定レベルのインフラストラクチャの実装が必要です。 このインフラストラクチャの最も重要な部分はエントリ ポイントです。 ユーザーがアプリケーションを起動するとき、オペレーティング システムはエントリ ポイントを呼び出します。これは、オペレーティング システムがアプリケーションを起動するための機能としてよく知られています。

従来、テクノロジに応じて、このコードの一部または全部を開発者が記述する必要がありました。 しかし、WPF では、アプリケーション定義のマークアップ ファイルを MSBuild ApplicationDefinition 項目として構成すると、次の MSBuild プロジェクト ファイルに示すように、このコードが自動生成されます。

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

分離コード ファイルにはコードが含まれているので、通常どおり、MSBuild Compile 項目としてマークされます。

これらの MSBuild 構成をアプリケーション定義のマークアップや分離コード ファイルに適用すると、MSBuild によって次のようなコードが生成されます。


Imports Microsoft.VisualBasic
Imports System ' STAThread
Imports System.Windows ' Application

Namespace SDKSample
    Public Class App
        Inherits Application
        Public Sub New()
        End Sub
        <STAThread>
        Public Shared Sub Main()
            ' Create new instance of application subclass
            Dim app As New App()

            ' Code to register events and set properties that were
            ' defined in XAML in the application definition
            app.InitializeComponent()

            ' Start running the application
            app.Run()
        End Sub

        Public Sub InitializeComponent()


...


        End Sub
    End Class
End Namespace
using System; // STAThread
using System.Windows; // Application

namespace SDKSample
{
    public class App : Application
    {
        public App() { }
        [STAThread]
        public static void Main()
        {
            // Create new instance of application subclass
            App app = new App();

            // Code to register events and set properties that were
            // defined in XAML in the application definition
            app.InitializeComponent();

            // Start running the application
            app.Run();
        }

        public void InitializeComponent()
        {


...


        }
    }
}

生成されるコードにより、アプリケーション定義にインフラストラクチャ コードが追加され、そこに Main というエントリ ポイント メソッドが含まれます。 STAThreadAttribute 属性が Main メソッドに適用され、WPF アプリケーションのメイン UI スレッドが WPF アプリケーションに必須の STA スレッドであることを示します。これが呼び出されると、Main は App の新しいインスタンスを作成し、続いて InitializeComponent メソッドを呼び出して、イベントを登録し、マークアップに実装されているプロパティを設定します。 InitializeComponent は自動生成されるので、Page および Window の実装とは異なり、InitializeComponent をアプリケーションから明示的に呼び出す必要はありません。 最後に、Run メソッドが呼び出され、アプリケーションを起動します。

現在のアプリケーションの取得

Application クラスのサービスはアプリケーション全体で共有されるため、Application クラスのインスタンスとして AppDomain につき 1 つだけ指定できます。 このことを強制するため、Application クラスはシングルトン クラスとして実装されます (「Implementing Singleton in C#」を参照)。つまり、インスタンスを 1 つだけ作成し、static Current プロパティを使用してインスタンスへの共有アクセスを提供します。

現在の AppDomainApplication オブジェクトへの参照を取得する方法を次のコードに示します。

            ' Get current application
            Dim current As Application = App.Current
// Get current application
Application current = App.Current;

Current は、Application クラスのインスタンスへの参照を返します。 Application 派生クラスへの参照が必要な場合、Current プロパティの値を、次の例に示すようにキャストしなければなりません。

            ' Get strongly-typed current application
            Dim appCurrent As App = CType(App.Current, App)
// Get strongly-typed current application
App app = (App)App.Current;

Current の値は、Application オブジェクトが有効である間はいつでも確認できます。 ただし、注意が必要です。 Application クラスがインスタンス化されると、Application オブジェクトの状態に一貫性が失われる期間が生じます。 この期間中、Application は、アプリケーション インフラストラクチャの確立、プロパティの設定、イベントの登録など、コードの実行に必要なさまざまな初期化タスクを実行します。 この期間中に Application オブジェクトを使用しようとすると、特に設定中の各種 Application プロパティにコードが依存している場合に、コードで予期しない結果が生じる可能性があります。

Application の実質的な有効期間は、初期化作業が完了した時点から始まります。

アプリケーションの有効期間

WPF アプリケーションの有効期間は、アプリケーションが起動されたこと、アプリケーションがアクティブ、および非アクティブになったこと、シャットダウンされたことなどを通知するために Application で発生するいくつかのイベントによって規定されます。

ここでは、次の項目について説明します。

  • スプラッシュ スクリーン
  • アプリケーションの起動
  • ユーザー インターフェイスの表示
  • コマンド ライン引数の処理
  • アプリケーションのアクティブ化および非アクティブ化
  • アプリケーションのシャットダウン
  • 未処理の例外
  • アプリケーションの有効期間イベント

スプラッシュ スクリーン

.NET Framework 3.5 SP1 以降では、スタートアップ ウィンドウ (スプラッシュ スクリーン) で使用されるイメージを指定できます。 SplashScreen クラスを使用すると、アプリケーションの読み込みの間、スタートアップ ウィンドウを簡単に表示できます。 SplashScreen ウィンドウは、Run を呼び出す前に作成されて表示されます。 詳細については、「アプリケーションの起動時間」および「方法 : スプラッシュ スクリーンを WPF アプリケーションに追加する」を参照してください。

アプリケーションの起動

Run が呼び出され、アプリケーションが初期化されると、アプリケーションの実行準備が整います。 このタイミングは、Startup イベントが発生したときに通知されます。


Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running


...


        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs, WindowState

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


...


        }
    }
}

アプリケーションの有効期間中のこの時点で一般的に行われるのは UI の表示です。

ユーザー インターフェイスの表示

一般的なスタンドアロン Windows アプリケーションは、実行を開始すると Window を開きます。 次のコードに示すように、Startup イベント ハンドラーはそれを行うことができる場所の 1 つです。

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App" 
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Open a window
            Dim window As New MainWindow()
            window.Show()
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Open a window
            MainWindow window = new MainWindow();
            window.Show();
        }
    }
}
メモメモ

スタンドアロン アプリケーションで最初にインスタンス化される Window は、既定でメイン アプリケーション ウィンドウになります。この Window オブジェクトは、Application.MainWindow プロパティによって参照されます。最初にインスタンス化された Window 以外のウィンドウをメイン ウィンドウにする必要がある場合は、MainWindow プロパティの値をプログラムで変更できます。

XBAP が最初に起動すると、一般的には Page にナビゲートされます。 コードは次のようになります。

<Application 
  x:Class="SDKSample.App"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  Startup="App_Startup" />

Imports System ' Uri, UriKind, EventArgs, Console
Imports System.Windows ' Application, StartupEventArgs
Imports System.Windows.Navigation ' NavigationWindow

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            CType(Me.MainWindow, NavigationWindow).Navigate(New Uri("HomePage.xaml", UriKind.Relative))
        End Sub
    End Class
End Namespace
using System; // Uri, UriKind, EventArgs, Console
using System.Windows; // Application, StartupEventArgs
using System.Windows.Navigation; // NavigationWindow

namespace SDKSample
{
    public partial class App : Application
    {        
        void App_Startup(object sender, StartupEventArgs e)
        {
            ((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
        }
    }
}

Startup の処理目的が Window を開くことまたは Page にナビゲートすることのみの場合は、代わりに StartupUri 属性をマークアップに設定できます。

StartupUri をスタンドアロン アプリケーションで使用して Window を開く方法を次の例に示します。

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

StartupUri を XBAP で使用して Page にナビゲートする方法の例を次に示します。

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

このマークアップは、ウィンドウを開くことについて、前のコードと同じ効果があります。

メモメモ

ナビゲーションの詳細については、「ナビゲーションの概要」を参照してください。

既定ではないコンストラクターを使用してウィンドウをインスタンス化する必要がある場合、ウィンドウのプロパティやサブプロパティを設定してから表示する必要がある場合、またはアプリケーションの起動時に指定されたコマンド ライン引数を処理する必要がある場合は、Window を開くために Startup イベントを処理する必要があります。

コマンド ライン引数の処理

Windows では、スタンドアロン アプリケーションはコマンド プロンプトまたはデスクトップから起動できます。 どちらの場合でも、アプリケーションにコマンド ライン引数を渡すことができます。単一のコマンド ライン引数 "/StartMinimized" を指定して起動されるアプリケーションの例を次に示します。

wpfapplication.exe /StartMinimized

アプリケーションの初期化中に、WPF はオペレーティング システムからコマンド ライン引数を取得し、StartupEventArgs パラメーターの Args プロパティ経由で、Startup イベント ハンドラーにそれらの引数を渡します。 コマンド ライン引数を取得および格納するには、次のようなコードを使用します。

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running
            ' Process command line args
            Dim startMinimized As Boolean = False
            Dim i As Integer = 0
            Do While i <> e.Args.Length
                If e.Args(i) = "/StartMinimized" Then
                    startMinimized = True
                End If
                i += 1
            Loop

            ' Create main application window, starting minimized if specified
            Dim mainWindow As New MainWindow()
            If startMinimized Then
                mainWindow.WindowState = WindowState.Minimized
            End If
            mainWindow.Show()
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs, WindowState

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running
            // Process command line args
            bool startMinimized = false;
            for (int i = 0; i != e.Args.Length; ++i)
            {
                if (e.Args[i] == "/StartMinimized")
                {
                    startMinimized = true;
                }
            }

            // Create main application window, starting minimized if specified
            MainWindow mainWindow = new MainWindow();
            if (startMinimized)
            {
                mainWindow.WindowState = WindowState.Minimized;
            }
            mainWindow.Show();
        }
    }
}

このコードは Startup を処理し、/StartMinimized コマンド ライン引数が指定されているかどうかを検証します。指定されている場合、WindowStateMinimized であるメイン ウィンドウを開きます。 WindowState プロパティはプログラムで設定する必要があるため、メイン Window はコードで明示的に開く必要があります。

XBAPs はコマンド ライン引数の取得や処理ができません。これは、ClickOnce 展開を使用して起動されるためです (「WPF アプリケーションの配置 (WPF)」を参照)。 ただし、起動に使用される URL のクエリ文字列パラメーターは取得して処理できます。

アプリケーションのアクティブ化および非アクティブ化

Windows では、ユーザーがアプリケーションを切り替えることができます。Alt キーを押しながら Tab キーを押すのが一般的なやり方です。 アプリケーションを切り替えるには、アプリケーションに、ユーザーが選択できる可視の Window が必要がです。 現在選択されている Window はアクティブ ウィンドウと呼ばれ (前面ウィンドウとも呼ばれる)、これがユーザー入力を受け取る Window になります。アクティブ ウィンドウを持つアプリケーションはアクティブ アプリケーション (または前面アプリケーション) と呼ばれます。アプリケーションは、次の場合にアクティブ アプリケーションになります。

  • 起動され、Window を表示した。

  • ユーザーがそのアプリケーションの Window を選択して別のアプリケーションから切り替えた。

アプリケーションがアクティブになったことを検出するには、Application.Activated イベントを処理します。

同様に、アプリケーションは次の場合に非アクティブになります。

  • ユーザーが現在のアプリケーションから別のアプリケーションに切り替えた。

  • アプリケーションがシャットダウンされた。

アプリケーションが非アクティブになったことを検出するには、Application.Deactivated イベントを処理します。

Activated イベントと Deactivated イベントを処理してアプリケーションがアクティブかどうかを判断する方法を次のコードに示します。

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  Activated="App_Activated" 
  Deactivated="App_Deactivated" />

Imports Microsoft.VisualBasic
Imports System ' EventArgs
Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private isApplicationActive As Boolean

        Private Sub App_Activated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application activated
            Me.isApplicationActive = True
        End Sub

        Private Sub App_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application deactivated
            Me.isApplicationActive = False
        End Sub
    End Class
End Namespace
using System; // EventArgs
using System.Windows; // Application

namespace SDKSample
{
    public partial class App : Application
    {
        bool isApplicationActive;

        void App_Activated(object sender, EventArgs e)
        {
            // Application activated
            this.isApplicationActive = true;
        }

        void App_Deactivated(object sender, EventArgs e)
        {
            // Application deactivated
            this.isApplicationActive = false;
        }
    }
}

Window もアクティブまたは非アクティブにできます。 詳細については、「Window.Activated」および「Window.Deactivated」を参照してください。

メモメモ

Application.ActivatedApplication.Deactivated も XBAPs に対しては発生しません。

アプリケーションのシャットダウン

アプリケーションの有効期間は、シャットダウンと同時に終了します。シャットダウンは次の理由で発生します。

  • ユーザーがすべての Window を閉じた。

  • ユーザーがメイン Window を閉じた。

  • ユーザーがログオフまたはシャットダウンして、Windows を終了した。

  • アプリケーション固有の条件が満たされた。

アプリケーションのシャットダウンの管理を支援するため、Application には Shutdown メソッド、ShutdownMode プロパティ、SessionEnding イベント、および Exit イベントが用意されています。

メモメモ

Shutdown は、UIPermission を持つアプリケーションでのみ呼び出すことができます。スタンドアロン WPF には必ずこのアクセス許可があります。ただし、インターネット ゾーン部分信頼のセキュリティ サンドボックス内で実行される XBAPs には含まれません。

シャットダウン モード

ほとんどのアプリケーションは、すべてのウィンドウが閉じられるか、メイン ウィンドウが閉じられると、シャットダウンします。 ただし、アプリケーションのシャットダウンに他のアプリケーション固有の条件が関係する場合もあります。 アプリケーションのシャットダウン条件は、ShutdownMode を次のいずれかの ShutdownMode 列挙値で設定できます。

ShutdownMode の既定値は OnLastWindowClose です。これは、アプリケーションの最後のウィンドウが閉じられると自動的にシャットダウンすることを意味します。 一方、メイン ウィンドウが閉じられたときにアプリケーションがシャットダウンするようにする必要がある場合は、ShutdownModeOnMainWindowClose に設定すると、WPF が自動的にシャットダウンします。 これを次の例に示します。

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    ShutdownMode="OnMainWindowClose" />

アプリケーション固有のシャットダウン条件がある場合は、ShutdownModeOnExplicitShutdown に設定します。 この場合は、プログラムで Shutdown メソッドを明示的に呼び出してアプリケーションをシャットダウンする必要があります。そうしないと、すべてのウィンドウが閉じた後も、アプリケーションは実行したままになります。 Shutdown は、ShutdownModeOnLastWindowClose または OnMainWindowClose の場合、暗黙に呼び出されます。

メモメモ

ShutdownMode は XBAP から設定できますが、無視されます。XBAP は、ブラウザーで他にナビゲートされた場合、または XBAP をホストするブラウザーが閉じられた場合に、必ずシャットダウンします。詳細については、「ナビゲーションの概要」を参照してください。

セッションの終了

ShutdownMode プロパティで記述されたシャットダウン条件は、アプリケーション固有です。 ただし、場合によっては、外部条件の結果としてシャットダウンすることもあります。 一般的な外部条件は、ユーザーが次の操作によって Windows セッションを終了した場合です。

  • ログオフ

  • シャットダウン

  • 再起動

  • 休止

Windows セッションの終了を検出するには、次の例に示すように、SessionEnding イベントを処理します。

<Application 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml"
    SessionEnding="App_SessionEnding" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_SessionEnding(ByVal sender As Object, ByVal e As SessionEndingCancelEventArgs)
            ' Ask the user if they want to allow the session to end
            Dim msg As String = String.Format("{0}. End session?", e.ReasonSessionEnding)
            Dim result As MessageBoxResult = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo)

            ' End session, if specified
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End Sub
    End Class
End Namespace
using System.Windows; // Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

namespace SDKSample
{
    public partial class App : Application
    {
        void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
        {
            // Ask the user if they want to allow the session to end
            string msg = string.Format("{0}. End session?", e.ReasonSessionEnding);
            MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);

            // End session, if specified
            if (result == MessageBoxResult.No)
            {
                e.Cancel = true;
            }
        }
    }
}

この例では、コードは ReasonSessionEnding プロパティ検証して、Windows セッションの終了方法を判別します。 この値は、ユーザーに対する確認メッセージの表示に使用されます。 ユーザーがセッションの終了を意図していない場合、コードで Cancel が true に設定されるため、Windows セッションは終了しません。

メモメモ

SessionEnding は XBAPs に対しては発生しません。

Exit

アプリケーションは、シャットダウン時に、アプリケーション状態の保存などの最終処理を必要とする場合があります。 そのような状況のためには、Exit イベントを処理できます。

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


...


</Application>
Imports System.IO ' StreamReader, FileMode
Imports System.IO.IsolatedStorage ' IsolatedStorageFile, IsolatedStorageFileStream

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private filename As String = "App.txt"



...


        Private Sub App_Exit(ByVal sender As Object, ByVal e As ExitEventArgs)
            ' Persist application-scope property to isolated storage
            Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
            Using stream As New IsolatedStorageFileStream(filename, FileMode.Create, storage)
            Using writer As New StreamWriter(stream)
                ' Persist each application-scope property individually
                For Each key As String In Me.Properties.Keys
                    writer.WriteLine("{0},{1}", key, Me.Properties(key))
                Next key
            End Using
            End Using
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs
using System.IO; // StreamReader, FileMode
using System.IO.IsolatedStorage; // IsolatedStorageFile, IsolatedStorageFileStream

namespace SDKSample
{
    public partial class App : Application
    {
        string filename = "App.txt";



...


        private 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 は、スタンドアロン アプリケーション、および XBAPs の両方で処理できます。 XBAPs では、次の場合に Exit が発生します。

  • XBAP が外部にナビゲートされた。

  • Internet Explorer 7 で、XBAP をホストしていたタブが閉じられた。

  • ブラウザーが閉じられた。

終了コード

ほとんどのアプリケーションは、ユーザー要求に応じてオペレーティング システムから起動されます。 しかし、別のアプリケーションから起動されて特定のタスクを実行するアプリケーションもあります。 起動されたアプリケーションをシャットダウンするときに、起動したアプリケーションがそのシャットダウン理由を必要とする場合があります。 そのような場合に、Windows ではアプリケーションがシャットダウン時にアプリケーション終了コードを返すことができます。 既定では、WPF アプリケーションは終了コード値として 0 を返します。

メモメモ

Visual Studio でデバッグする場合、アプリケーション終了コードは、アプリケーションのシャットダウン時に、[出力] ウィンドウに次のようなメッセージと共に表示されます。

The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).

[出力] ウィンドウを開くには、[表示] メニューの [出力] をクリックします。

終了コードを変更するには、Shutdown(Int32) オーバーロードを呼び出します。これが、終了コードとして整数値の引数を受け付けます。

' Shutdown and return a non-default exit code
Application.Current.Shutdown(-1)
// Shutdown and return a non-default exit code
Application.Current.Shutdown(-1);

Exit イベントを処理することで、終了コードの値を検出して変更できます。 Exit イベント ハンドラーには ExitEventArgs が渡され、ApplicationExitCode プロパティによって終了コードへのアクセスが提供されます。 詳細については、「Exit」を参照してください。

メモメモ

終了コードは、スタンドアロン アプリケーション、および XBAPs のいずれでも設定できます。ただし、XBAPs では終了コード値は無視されます。

未処理の例外

アプリケーションは、予期しない例外が発生したときなどに、異常条件によりシャットダウンする可能性があります。 この場合、アプリケーションにはその例外を検出して処理するためのコードがありません。 このような例外はハンドルされない例外と呼ばれ、アプリケーションが閉じる前に次の図に示すような通知が表示されます。

ハンドルされない例外通知

ユーザー エクスペリエンスの観点から、アプリケーションではこの既定の動作を使用せず、次の一部またはすべてを行うことをお勧めします。

  • わかりやすい情報を表示する。

  • アプリケーションを続行するよう試みる。

  • 開発者向けの詳細な例外情報を Windows イベント ログに記録する。

このサポートを実装するには、ハンドルされない例外を検出できることが前提となります。ハンドルされない例外を検出するには、発生する DispatcherUnhandledException イベントを検出します。

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  DispatcherUnhandledException="App_DispatcherUnhandledException" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application
Imports System.Windows.Threading ' DispatcherUnhandledExceptionEventArgs

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As DispatcherUnhandledExceptionEventArgs)
            ' Process unhandled exception


...


            ' Prevent default unhandled exception processing
            e.Handled = True
        End Sub
    End Class
End Namespace
using System.Windows; // Application
using System.Windows.Threading; // DispatcherUnhandledExceptionEventArgs

namespace SDKSample
{
    public partial class App : Application
    {
        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            // Process unhandled exception


...


            // Prevent default unhandled exception processing
            e.Handled = true;
        }
    }
}

DispatcherUnhandledException イベント ハンドラーには、未処理の例外に関するコンテキスト情報を含む DispatcherUnhandledExceptionEventArgs パラメーターが渡されます。この情報には、例外自体 (DispatcherUnhandledExceptionEventArgs.Exception) も含まれます。 この情報を使用して、例外の処理方法を確認できます。

DispatcherUnhandledException を処理するときは、必ず DispatcherUnhandledExceptionEventArgs.Handled プロパティを true に設定します。そうしないと、WPF はその例外を未処理のままと見なし、先に説明した既定の動作に戻ります。 ハンドルされない例外が発生し、かつ DispatcherUnhandledException イベントが処理されないか、イベントが処理されても Handled の設定が false である場合、アプリケーションは直ちにシャットダウンします。 また、他の Application イベントは発生しません。 したがって、アプリケーションのシャットダウン前に実行する必要があるコードがある場合は、DispatcherUnhandledException を処理する必要があります。

アプリケーションは、ハンドルされない例外の結果、シャットダウンする可能性がありますが、通常は、次のセクションで示すように、ユーザーの要求に呼応する形でシャットダウンします。

アプリケーションの有効期間イベント

スタンドアロン アプリケーションと XBAPs とで、有効期間が厳密に同じというわけではありません。スタンドアロン アプリケーションの有効期間内の主なイベントとその発生順を次の図に示します。

スタンドアロン アプリケーション - アプリケーション オブジェクト イベント

同様に、XBAP の有効期間内の主要イベントとその発生順を次の図に示します。

XBAP - アプリケーション オブジェクト イベント

その他のアプリケーション サービス

アプリケーションの有効期間の管理に加えて、Application には次のようなサービスが用意されています。

  • 共有アプリケーション スコープのプロパティ

  • 共有アプリケーション スコープのリソース

  • アプリケーションのリソース、コンテンツ、および起点サイトに関するデータ ファイル

  • ウィンドウの管理

  • ナビゲーション管理

共有アプリケーション スコープのプロパティ

アプリケーションの Properties プロパティは、アプリケーション全体で共有できる状態を公開します。 Properties の使用例を次に示します。

      ' Set an application-scope property with a custom type
      Dim customType As 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
      Dim customType As CustomType = CType(Application.Current.Properties("CustomType"), CustomType)
// 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"];

詳細については、以下のトピックを参照してください。

共有アプリケーション スコープのリソース

アプリケーションの Resources プロパティは、アプリケーション全体で開発者が UI リソースを共有できるようにします。 Resources の使用例を次に示します。

      ' Set an application-scope resource
      Application.Current.Resources("ApplicationScopeResource") = Brushes.White


...


      ' Get an application-scope resource
      Dim whiteBrush As Brush = CType(Application.Current.Resources("ApplicationScopeResource"), Brush)
// Set an application-scope resource
Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;


...


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

詳細については、以下のトピックを参照してください。

アプリケーションのリソース、コンテンツ、および起点サイトに関するデータ ファイル

WPF アプリケーションは、リソース ファイル、コンテンツ ファイル、起点サイト ファイルなど、さまざまな種類のコードではないデータ ファイルを管理できます。 これらの種類のデータ ファイルを読み込むには、次のようなヘルパー メソッドを使用できます。

ウィンドウの管理

ApplicationWindow には密接な関係があります。 これまで見てきたように、アプリケーションの有効期間は、ShutdownMode プロパティとして指定されているウィンドウの有効期間に依存する場合があります。 Application は、メイン アプリケーション ウィンドウに指定されているウィンドウがどれかを記録し (Application.MainWindow)、現在インスタンス化されているウィンドウのリストを維持します (Application.Windows)。

詳細については、「WPF ウィンドウの概要」を参照してください。

ナビゲーション管理

ナビゲーション機能のあるスタンドアロン アプリケーション (NavigationWindow および Frame を使用) または XBAPs では、Application はアプリケーション内でのあらゆるナビゲーションを検出し、必要に応じて次のイベントが発生します。

Application はさらに、GetCookie および SetCookie を使用して、Cookie の作成、永続化、および取得を行う機能を任意の種類のアプリケーションに提供します。

詳細については、「ナビゲーションの概要」を参照してください。

参照

参照

Application

概念

WPF ウィンドウの概要

ナビゲーションの概要

WPF アプリケーションのリソース ファイル、コンテンツ ファイル、およびデータ ファイル

WPF におけるパッケージの URI

アプリケーション開発

その他の技術情報

アプリケーション モデルに関する「方法」トピック