マークアップ拡張機能と XAML

更新 : 2007 年 11 月

ここでは、構文上の規則、目的、およびその基になるクラス オブジェクト モデルを含む Extensible Application Markup Language (XAML) のマークアップ拡張機能の概念について説明します。

このトピックには次のセクションが含まれています。

  • XAML プロセッサとマークアップ拡張機能
  • 基本的なマークアップ拡張構文
  • WPF 固有のマークアップ拡張機能
  • XAML で定義されたマークアップ拡張機能
  • マークアップ拡張構文の詳細
  • 関連トピック

XAML プロセッサとマークアップ拡張機能

XAML プロセッサは、仕様に従った言語として XAML を (コンパイルまたは解釈によって) 受け入れることができ、ランタイム オブジェクト モデルが使用する基になるクラスを XAML 仕様に従って生成できるプログラムとして定義されます。既定では、このようなプロセッサは、属性値をリテラル文字列として解釈するか、または属性値をオブジェクトに変換します。変換は、属性の型またはその属性に固有の型コンバータに基づいて行います。しかし、シナリオによっては、別の動作が必要な場合もあります。たとえば、XAML プロセッサに対し、ある属性値を、既に構築したオブジェクトや静的オブジェクトへの参照として処理するよう指示できます。または、XAML プロセッサに対し、オブジェクトのコンストラクタに既定以外の引数を渡す構文を使用するよう指示できます。これは、既定で指定された XAML プロセッサの動作からは外れています。

基本的なマークアップ拡張構文

マークアップ拡張機能は、属性使用のプロパティ、プロパティ要素使用のプロパティ、またはこれらの両方に値を指定するために実装できます。

属性値を指定するために使用するときは、XAML プロセッサに対してマークアップ拡張機能を区別する構文として、始め中かっこと終わり中かっこ ({ および }) が使用されます。マークアップ拡張機能の種類は、次の始め中かっこの直後の文字列トークンによって識別されます。

プロパティ要素構文で使用する場合、マークアップ拡張機能は、プロパティ要素値を指定するために使用されるその他の要素と表示上は同じになります。つまり、山かっこ (<>) で囲まれたマークアップ拡張機能クラスを要素として参照する XAML 要素宣言になります。

WPF 固有のマークアップ拡張機能

WPF プログラミングで最も一般的なマークアップ拡張機能には、リソース参照 (StaticResource と DynamicResource) をサポートする機能、およびデータ バインディング (Binding) をサポートする機能があります。

StaticResource は、既に定義されたリソースの値を置き換えることによって、XAML プロパティの値を指定します。詳細については、「StaticResource のマークアップ拡張機能」を参照してください。

DynamicResource は、リソースに対するランタイム参照になる値を優先させることによって、XAML プロパティの値を指定します。動的リソース参照では、このようなリソースにアクセスするたびに、強制的に新しいルックアップが行われます。詳細については、「DynamicResource のマークアップ拡張機能」を参照してください。

Binding は、要素に適用されるデータ コンテキストごとに、プロパティのデータ バインドされた値を指定します。このマークアップ拡張機能では、データ バインディングを指定するためのインライン構文を大量に使用できるようになるため、比較的複雑です。詳細については、「バインディングのマークアップ拡張機能」を参照してください。

RelativeSource は、ランタイム要素ツリーに存在する可能性があるいくつかの関係をナビゲーションできる Binding のソース情報を指定します。これによって、周囲の要素ツリーをすべて知っていなくても、多目的のテンプレートまたはコードで作成されたバインディングの特殊なソースの指定が行われます。詳細については、「RelativeSource のマークアップ拡張機能」を参照してください。

TemplateBinding は、コントロール テンプレートが、テンプレートを使用するクラスのオブジェクト モデル定義プロパティから取得される、テンプレートが適用されたプロパティの値を使用できるようにします。詳細については、「TemplateBinding のマークアップ拡張機能」を参照してください。TemplateBinding の実際の使用方法の詳細については、「ControlTemplate を使用したスタイル設定のサンプル」を参照してください。

XAML で定義されたマークアップ拡張機能

XAML の WPF アプリケーションに固有ではなく、言語としての XAML の仕様に含まれるマークアップ拡張機能がいくつか存在します。これらは、一般的な使用法の構文内では、通常は x: プレフィックスで識別できます。これらの言語要素に対する WPF の実装は、実装を提供するために同じ MarkupExtension 基本クラスを使用します。

ms747254.alert_note(ja-jp,VS.90).gifメモ :

x: プレフィックスは、XAML アプリケーションまたはドキュメントのルート要素において、XAML 名前空間の一般的な XML 名前空間の割り当てに使用されます。たとえば、Microsoft Visual Studio 2005 テンプレートは、この x: の割り当てを使用して XAML ファイルを開始します。独自の XML 名前空間の割り当てで別のプレフィックスを選択できますが、このドキュメントでは、WPF 名前空間またはその他の任意の CLR 名前空間や XML 名前空間ではなく、XAML 名前空間の定義済みの部分であるエンティティを識別する方法として、既定の x: の割り当てを想定しています。

x:Type は、指定した型の Type オブジェクトを示します。これは、スタイルとテンプレートで最もよく使用されます。詳細については、「x:Type マークアップ拡張機能」を参照してください。

x:Static は、直接的にはプロパティの値の型ではなくても、その型に評価することができる値型コード エンティティから静的な値を生成します。詳細については、「x:Static のマークアップ拡張機能」を参照してください。

x:Null は、XAML プロパティの値として null を指定します。詳細については、「x:Null のマークアップ拡張機能」を参照してください。

x:Array は、XAML の構文での一般的な配列の作成をサポートします。基本要素とコントロール モデルで提供されているコレクションのサポートをあえて使用しない場合に使用します。詳細については、「x:Array のマークアップ拡張機能」を参照してください。

マークアップ拡張構文の詳細

*Extension クラス

各マークアップ拡張機能の動作は、MarkupExtension から派生する *Extension クラスを使用して XAML プロセッサに対して識別され、ProvideValue メソッドの実装を提供します。各拡張機能に対するこのメソッドは、マークアップ拡張機能が評価されるとどのようなオブジェクトが返されるかを定義します。返されたオブジェクトは、通常、マークアップ拡張機能に渡されたさまざまな文字列トークンを使用して、インスタンス化または設定されます。

たとえば、StaticResourceExtension クラスは、実際のリソース検索の外見的な実装を提供するため、その ProvideValue 実装は必要なオブジェクトを返します。その際入力として、その実装の x:Key によってリソースを検索するために使用される文字列を使用します。既存のマークアップ拡張機能を使用する場合は、この実装の詳細の大部分は重要ではありません。

後続の文字列トークンの拡張クラスの解釈

マークアップ拡張機能識別子の後に続き、まだ中かっこの中にある文字列トークンは、次の方法のいずれかで XAML プロセッサに解釈されます。

  • コンマは常に個別のトークンの区切りまたは区切り記号を表します。したがって、リテラルのコンマはマークアップ拡張機能に渡すことができません。

  • 個別の区切られたトークンに、等号が含まれない場合は、各トークンはコンストラクタ引数として扱われます。各コンストラクタ パラメータは、その署名で想定される型として、その署名で想定される適切な順序で指定する必要があります。

    ms747254.alert_note(ja-jp,VS.90).gifメモ :

    XAML プロセッサは、ペアの数の引数の数に一致するコンストラクタを呼び出す必要があります。このため、カスタム マークアップ拡張機能を実装する場合は、複数のパラメータに同じ引数の数を指定しないでください。同じパラメータ数のマークアップ拡張機能コンストラクタが複数存在する場合に発生する動作については、定義されません。

  • 個別の区切られたトークンに等号が含まれている場合、XAML プロセッサは最初にマークアップ拡張機能の既定のコンストラクタを呼び出します。その後、各 "名前=値" のペアは、マークアップ拡張機能に存在するプロパティ名、およびそのプロパティに割り当てられる値として解釈されます。

  • マークアップ拡張機能において、コンストラクタの動作とプロパティの設定の動作に類似点がある場合は、どちらの動作を使用しても問題はありません。複数の設定可能なプロパティを持つマークアップ拡張機能では、マークアップがより意図的なものにされ、コンストラクタ パラメータを間違って置き換える可能性が低い場合に限り、"プロパティ=値" のペアの方がよく使用されます ("プロパティ=値" のペアを指定した場合、それらのプロパティは任意の順序になります)。また、マークアップ拡張機能によって、設定可能なプロパティのすべてを設定するコンストラクタ パラメータが提供されるという保証はありません。たとえば、Binding は、"プロパティ=値" の形式で拡張機能を使用して設定可能な複数のプロパティを持つマークアップ拡張機能ですが、Binding は、既定のコンストラクタと初期パスを設定したコンストラクタの 2 つのコンストラクタのみをサポートします。

リテラル中かっこのエスケープ

XAML プロセッサで処理する属性は、マークアップ拡張機能のインジケータとして中かっこを使用します。必要に応じて、空の中かっこのペアとその後に続くリテラル中かっこを使用したエスケープ シーケンスを入力することによって、リテラル中かっこ文字属性値を生成することもできます。「{} エスケープ シーケンス/マークアップ拡張機能」を参照してください。

拡張構文の入れ子

複数のマークアップ拡張機能は入れ子にすることができ、各マークアップ拡張は、最も深いものが最初に評価されます。次に例を示します。

<Setter Property="Background"

Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

マークアップ拡張機能とプロパティ要素の構文の詳細

マークアップ拡張構文は、プロパティ要素値を設定するオブジェクト要素として使用した場合、XAML で使用できる通常の要素と見た目上は区別できません。この状況において、通常の要素とマークアップ拡張機能の実用上の違いは、マークアップ拡張機能は、型指定された値に評価されるか式として優先されるため、別のプログラミング モデルでの遅延バインド プロパティの扱われ方と同様、発生する可能性があるプロパティ値の型エラーの機構が異なるという点です。通常の要素は、型と、コンパイル時にすぐに設定されるプロパティに対して評価されます。

ほとんどのマークアップ拡張機能は、プロパティ要素を埋め込むためにオブジェクト要素構文で使用される場合は、内側にコンテンツまたはそれ以外のプロパティ要素の構文を持ちません。このため、オブジェクト要素タグを閉じ、子要素は指定しません。オブジェクト要素が XAML プロセッサで検出されるたびに、そのクラスのコンストラクタが呼び出され、解析された要素から作成されたオブジェクトをインスタンス化します。マークアップ拡張機能クラスも同じです。このため、マークアップ拡張機能をオブジェクト要素構文で使用できるようにする場合は、既定のコンストラクタを指定する必要があります。一部の既存のマークアップ拡張機能には、有効な初期化のために指定する必要がある必須プロパティ値が少なくとも 1 つはあります。その場合、通常、そのプロパティ値はオブジェクト要素のプロパティ属性として指定されます。「XAML 名前空間 (x:) 言語機能」および「WPF 名前空間の XAML 拡張機能」の各リファレンス ページで、必須プロパティを持つマークアップ拡張機能 (および必須プロパティの名前) について説明します。リファレンス ページでは、オブジェクト要素構文と属性構文のどちらかが特定のマークアップ拡張機能に対して許可されない場合についても説明します。特に注意する必要があるケースは、「x:Array のマークアップ拡張機能」です。この場合、その配列のコンテンツを指定する必要があるため、属性構文をサポートできません。配列のコンテンツは、一般的なオブジェクトとして処理されるため、属性の既定の型コンバータは使用できません。また、「x:Array のマークアップ拡張機能」には Type パラメータが必要です。

参照

概念

XAML の概要

参照

StaticResource のマークアップ拡張機能

バインディングのマークアップ拡張機能

DynamicResource のマークアップ拡張機能

x:Type マークアップ拡張機能

その他の技術情報

XAML 名前空間 (x:) 言語機能

WPF 名前空間の XAML 拡張機能