今まで Windows Forms アプリケーションをやっていて WPF をまともに触ったことがありませんでした。ちょうど時間ができたので WPF をこれから触ってみたいと思います。そこで覚えたことを忘れないようにメモ書きしてみます。
エントリポイントについて
まず WPF アプリケーションを作成して思ったことが エントリポイントが隠されるように自動生成されているということです。Application クラスを定義した XAML ファイル(VB:Application.xaml、C#:App.xaml)をビルドすると obj フォルダの中にエントリポイントが定義されたファイルが自動生成されます。その中には Application クラスが Partial で定義されています。この Application クラスは WPF 用のもので System.Windows 名前空間にあります。ちなみに Windows Forms の Application クラスは System.Windows.Forms 名前空間にあります。
Partial Public Class Application
Inherits System.Windows.Application
・・・
<System.STAThreadAttribute(), _
System.Diagnostics.DebuggerNonUserCodeAttribute()> _
Public Shared Sub Main
Dim app As Application = New Application
app.InitializeComponent
app.Run
End Sub
End Class
Windows Forms の場合 Visual Basic ではエントリポイントをコーディングしていました(アプリケーション フレームワークを使用する方法もあります)。C# ではエントリポイントが自動生成されるものの、隠されてはいませんでした。そのため、Main メソッドの中でアプリケーションの開始時・終了時の処理(初期化処理や二重起動のチェックなど)ができました。
ということは WPF ではアプリケーションの開始時や終了時のタイミングで処理ができないのかというと、そんなことはありません。Application クラスはアプリケーションの開始時に Startup イベントが発生します。そこでアプリケーションの初期化処理や二重起動のチェックをするコードを書くことができます。この他にアプリケーションの終了時に Exit イベントが発生し、未処理例外を処理する DispatcherUnhandledException イベントもあります。
このイベントを見て気づいたことが WPF の Application クラスは、Windows Forms の Visual Basic のアプリケーション フレームワークで使用している WindowsFormsApplicationBase クラスに似ているということです。その簡易版というような感じがします。
WPF でもエントリポイントを独自にコーディングすることができます。ただし Application クラスを定義した XAML ファイルが読み込めなくなります(たぶん)。その代わり WindowsFormsApplicationBase クラスなどを使用できるといったメリットがあります。
自動生成されたエントリポイントを使用するかしないかを考えた場合、通常は自動生成されたエントリポイントを使用するだけで十分だと思います。どうしても Application クラスのイベントだけではアプリケーションの管理ができない場合のみ、独自にエントリポイントを定義したほうが良さそうです。
Visual Basic のアプリケーション フレームワーク
WPF の Visual Basic にもアプリケーション フレームワークがあります。WPF ではエントリポイントの指定と Application クラスのプロパティ設定に使用されています。これを有効にするとエントリポイントが自動生成されるようになります。無効にするとエントリポイントを独自にコーディングする必要があります(つまりエントリポイントが定義してあるファイルが自動生成されなくなります)。
Windows Forms の WindowsFormsApplicationBase クラスを利用するにはエントリポイントを独自にコーディングしなければいけないため、アプリケーション フレームワークを無効にする必要あります。Windows Forms の場合と逆になっているところが面白いですね。
まとめ
- エントリポイントは自動生成されたコードを使用する(Visual Basic ではこのためにアプリケーション フレームワークを有効にする)。
- アプリケーションの開始時の処理は Application.Startup イベントを使用する。
- アプリケーションの終了時の処理は Application.Exit イベントを使用する。
- アプリケーションの未処理例外の処理は Application.DispatcherUnhandledException イベントを使用する。
WPF のエントリポイントは C# であっても隠されているというのが驚きでした。これはコードとは別に XAML を使用するための影響だと思います。その代わりアプリケーションの管理は WPF 用の Application クラスがやっています。処理を組み込む場合に Startup イベントや Exit イベントなどを使用するだけでよくなったので、処理がしやすくなったように思います。