分離コードと XAML
更新 : 2007 年 11 月
分離コードとは、XAML ページがアプリケーションにコンパイルされる際に XAML プロセッサによって作成されるコードと結合されるコードを表す用語です。ここでは、分離コードの要件と、XAML 内のコードの代替インライン コード機構について説明します。
このトピックには次のセクションが含まれています。
- 必要条件
- 分離コード、イベント ハンドラ、および部分クラスの要件
- x:Code
- インライン コードの制限
- 関連トピック
必要条件
このトピックでは、「XAML の概要」を通読していることと、CLR およびオブジェクト指向プログラミングに関する基礎知識があることを前提にしています。
分離コード、イベント ハンドラ、および部分クラスの要件
部分クラスは、ルート要素として使用されたクラスの型から、派生する必要があります。分離コード内の部分クラス定義で、派生を空白のままにすることは可能です。ただし、指定しなくても、コンパイル結果ではページ ルートが部分クラスの基本クラスと想定されます (部分クラスのマークアップの半分がページ ルートを基本として指定したため)。
記述するイベント ハンドラは、x:Class で識別される CLR 名前空間内の部分クラスで定義されたインスタンス メソッドである必要があります。XAML プロセッサがイベント ハンドラの検索を異なるクラス スコープで行うように、イベント ハンドラの名前を修飾することはできません。また、静的メソッドをイベント ハンドラとして使用することもできません。
ハンドラは、適切なイベントのデリゲートと一致する必要があります。
Microsoft Visual Basic .NET 言語の場合に限り、言語固有の Handles キーワードを使用すると、ハンドラを、XAML 内の属性に関連付ける代わりに、ハンドラ宣言内のインスタンスとイベントに関連付けることができます。ただし、この手法にはいくつかの制限もあります。一定のルーティング イベント シナリオや添付イベントなど、Handles でサポートできない WPF イベント システムの特定機能が存在するためです。詳細については、「Visual Basic と WPF のイベント処理」を参照してください。
x:Code
x:Code は、XAML で定義されるディレクティブ要素です。x:Code ディレクティブ要素には、インラインのプログラミング コードを含めることができます。インラインで定義されたコードは、同一ページ上の XAML と対話できます。C# のインライン コードを次の例に示します。コードは x:Code 要素内に含まれており、XML のコンテンツをエスケープする <CDATA[...]]> でコードを囲んでいるのは、XAML プロセッサ (XAML スキーマまたは WPF スキーマを解釈) がこのコンテンツをリテラルに XML として解釈しないようにする必要があるためです。
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyNamespace.MyCanvasCodeInline"
>
<Button Name="button1" Click="Clicked">Click Me!</Button>
<x:Code><![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
button1.Content = "Hello World";
}
]]></x:Code>
</Page>
インライン コードの制限
XAML ベースのアプリケーションには、インライン コードを使用しないようにするか、限定的に使用することを考慮する必要があります。アーキテクチャおよびコーディングの原理という点では、マークアップと分離コードを切り離しておくことによって、デザイナと開発者の役割もはっきりと区別できます。より技術的なレベルで言えば、インライン コードとして作成するコードは記述が面倒な場合があります。常に XAML ページに生成された部分クラス内に記述することとなり、既定の XML 名前空間のマッピングしか使用できないためです。using ステートメントを追加できないため、作成する API 呼び出しの多くを完全に修飾する必要があります。既定の WPF マッピングには、WPF アセンブリ内に存在する CLR 名前空間のほとんどが含まれますが、すべてではありません。他の CLR 名前空間内に含まれる API への呼び出しを完全に修飾することが必要になります。また、インライン コードに複数のクラスを定義することはできません。すべてのコード エンティティが、生成された部分クラス内のメンバまたは変数として存在する必要があります。マクロ、グローバル変数やビルド変数に対する #ifdef など、言語固有のその他のプログラミング機能も使用できません。詳細については、「x:Code XAML ディレクティブ要素」を参照してください。