XAML の概要

更新 : 2007 年 11 月

ここでは、Extensible Application Markup Language (XAML) 言語の機能と、XAML を使用して実際に Windows Presentation Foundation (WPF) アプリケーションを記述する方法について説明します。ここで説明する XAML は、Windows Presentation Foundation (WPF) によって実装されている XAML です。XAML 自体は、言語に関する Windows Presentation Foundation (WPF) よりも大きな概念です。

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

  • フロー制御をサポートする宣言型言語
  • XAML オブジェクト要素
  • プロパティの設定
  • 参照値とマークアップ拡張機能
  • 型コンバータによって実現される属性値
  • コレクション型と XAML コレクション プロパティ
  • XAML コンテンツ プロパティ
  • XAML の大文字/小文字と空白
  • XAML 構文の詳細
  • XAML ルート要素と XML 名前空間
  • イベントと XAML 分離コード
  • x:Name
  • 添付プロパティと添付イベント
  • 基本クラスと XAML
  • XAML のセキュリティ
  • コードからの XAML の読み込み
  • 次の内容
  • 関連トピック

フロー制御をサポートする宣言型言語

XAML は、.NET Framework プログラミング モデルにおける UI の作成を単純化します。表示される UI 要素を宣言的 XAML マークアップで作成し、分離コード ファイルを使用して UI 定義をランタイム ロジックから分離させることができます。分離コード ファイルは部分クラス定義を通じてマークアップに結合されます。XML は宣言型の言語であり、フロー制御のモデルは示されていないため、このようにコードをマークアップに結び付けることができることは、XAML にとって大きな意味があります。XML ベースの宣言型言語では、プロトタイプから製品版に至るまでのインターフェイスをきわめて直感的に作成することができます。Web のデザインやテクノロジの経験がある人々にとっては特にそう言えます。他のほとんどのマークアップ言語と違って、XAML ではマネージ オブジェクトのインスタンス化が直接表現されます。全体的な設計がこのような基本方針に基づいているため、コードの作成やデバッグの際に、XAML で作成されたオブジェクトに簡単にアクセスすることができます。

XAML ファイルは XML ファイルです。拡張子は通常 .xaml です。

次の例は、UI の一部としてボタンを作成する XAML です。この例から、必要なマークアップがいかに少ないかがわかります。作成されたボタンには、テーマ スタイルを通じて既定のビジュアル プレゼンテーションが割り当てられ、クラス設計を通じて既定の動作が割り当てられます。

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

XAML オブジェクト要素

XAML には、オブジェクト要素をクラスや構造体に、属性をプロパティやイベントに、XML 名前空間を CLR 名前空間にそれぞれマッピングする一連の規則があります。XAML 要素は、参照先のアセンブリで定義されている Microsoft .NET 型にマッピングされ、属性はそれらの型のメンバにマッピングされます。

前の例では、<StackPanel> (および対応する終了タグ) と <Button/> (およびいくつかの属性。属性については後で説明) という 2 つのオブジェクト要素が指定されています。StackPanel と Button という文字列は、WPF によって定義されているクラスの名前にそれぞれマッピングされます。これらのクラスは、WPF アセンブリの一部になっています。オブジェクト要素タグを指定すると、XAML プロセッサに対する命令が作成されて、XAML ページが読み込まれるときに、指定したクラスの新しいインスタンスが作成されます。各インスタンスは、基になるクラスまたは構造体の既定のコンストラクタを呼び出して、その結果を格納することによって作成されます。クラスまたは構造体が XAML でオブジェクト要素として使用可能であるためには、そのクラスまたは構造体の既定の (パラメータなしの) パブリック コンストラクタが公開されている必要があります。

プロパティの設定

XAML のプロパティは、さまざまな構文を使用してオブジェクト要素のプロパティを設定することによって設定されます。特定のプロパティに対して使用できる構文は、設定するプロパティの特性によって異なります。

プロパティの値を設定すると、オブジェクト要素に機能や特性が追加されます。オブジェクト要素の基になるオブジェクト インスタンスの初期状態は、既定のコンストラクタの動作に基づきます。通常、アプリケーションでは当該オブジェクトの既定のインスタンスをそのままの状態では使用しません。

属性構文

XAML では、多くの場合、プロパティを属性として表現できます。属性構文は最も簡潔なプロパティ設定構文であり、マークアップ言語を使用した経験がある開発者が最も直感的に使用できるのがこの構文です。たとえば、次のマークアップは、赤いテキストと青い背景を持つボタンを作成します。このボタンには、Content として指定された表示テキストも含まれています。

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

プロパティ要素の構文

オブジェクト要素のプロパティの中には、プロパティ値を指定するために必要なオブジェクトや情報を単純な文字列では適切に表現できないために、属性構文を使用できないものもあります。そのような場合は、プロパティ要素構文と呼ばれる別の構文を使用できます。プロパティ要素構文は、タグの内容を使用して格納要素のプロパティを設定します。一般に、この内容は、そのプロパティが (通常は別のオブジェクト要素として指定される、値設定インスタンスを使用して) 値として受け取る型のオブジェクトです。プロパティ要素自体の構文は、<TypeName.Property> となります。内容を指定した後は、他の要素の場合と同様に終了タグ (構文 </TypeName.Property>) を使用してプロパティ要素構文を終了します。属性構文とプロパティ要素構文の両方がサポートされているプロパティでは、空白の処理などの細かい点で多少の違いが生じることはありますが、原則として、どちらの構文を使用しても同じ結果になります。属性構文を使用できる場合は、通常、属性構文を使用した方が便利で、マークアップもよりコンパクトになります。ただし、これは単なるスタイルの問題であり、技術的な制限ではありません。次の例では、前の属性構文の例で設定したのと同じプロパティを設定しています。ただし、ここでは、Button のすべてのプロパティに対してプロパティ要素構文を使用しています。

<Button>
  <Button.Background>
    <SolidColorBrush Color="Blue"/>
  </Button.Background>
  <Button.Foreground>
    <SolidColorBrush Color="Red"/>
  </Button.Foreground>
  <Button.Content>
    This is a button
  </Button.Content>
</Button>

XAML のプロパティ要素構文は、XML の基本的なマークアップ解釈と著しく異なる点の 1 つです。XML では、<TypeName.Property> は別の 1 つの要素と見なされ、TypeName を親要素とする子要素という必然的な関係は考慮されません。XAML においては、<TypeName.Property> は、Property が TypeName のプロパティであって、プロパティ要素の内容で設定されるものであるということをそのまま意味しており、たまたまドットが含まれる同様の名前を持った別個の要素とは見なされません。

プロパティとクラスの継承

WPF 要素の XAML 属性として使用されるプロパティは多くの場合、基本クラスから継承されます。たとえば、前の例の Background プロパティは、クラス定義や反映される結果、またはドキュメントを見ればわかるように、Button クラスで直接宣言されているプロパティではありません。実際には、Background は基本 Control クラスから継承されます。

WPF XAML 要素のこのクラス継承動作も、XML の基本的なマークアップ解釈と著しく異なる点の 1 つです。XAML の要素一式およびその使用可能属性は、DTD 形式や XSD 形式など XML プログラミングで通常使用されるスキーマを使用して正確かつ完全に表現することが困難ですが、この原因の 1 つに、クラスの継承 (特に中間の基本クラスが抽象クラスである場合) があります。また、XAML の "X" は拡張可能 ("extensible") であることを意味しており、拡張可能であるということは、"WPF にとって XAML は何であるか" という問題について、どのような表現も完全ではないことになります (ただし、別個に XML 名前空間の定義を保持することでこの問題は補完できます。この概念については後のセクションで説明します)。

参照値とマークアップ拡張機能

マークアップ拡張機能は XAML の概念です。属性構文では、中かっこ ({ と }) によってマークアップ拡張機能の使用を示します。これにより、XAML プロセッサの通常の処理 (リテラル文字列か、直接文字列に変換できる値のいずれかとして属性値を扱う処理) がエスケープされます。

参照型の値を受け取るプロパティでは、プロパティ要素構文 (常に新しいインスタンスが作成されます) か、マークアップ拡張機能によるオブジェクト参照を使用することが必要になることがあります。マークアップ拡張機能を使用すると、既存のインスタンスを返すことができます。これによって使用範囲が広がるだけでなく、オブジェクトのオーバーヘッドも少なくなります。

マークアップ拡張機能を使用して属性値を指定する場合、その属性値は、該当するマークアップ拡張機能に対応するクラス内のロジックで指定することになります。WPF アプリケーション プログラミングで使用される最も一般的なマークアップ拡張機能には、データ バインディング表現に使用する Binding、およびリソース参照 StaticResourceDynamicResource があります。マークアップ拡張機能を使用すると、属性構文でオブジェクトを直接インスタンス化することのできないプロパティでも、属性構文を使用してプロパティの参照値を指定でき、また、XAML のプロパティにはそのプロパティの型を持つ値を指定するという要件に基づく通常の動作とは異なる動作を有効にすることもできます。

たとえば、次の例では、属性構文を使用して Style プロパティの値を設定しています。Style プロパティは Style クラスのインスタンスを受け取ります。これは参照型であるため、既定では属性構文の文字列内に指定することはできません。しかし、この例では、属性が StaticResource のマークアップ拡張機能を参照しています。このマークアップ拡張機能が処理されると、リソース ディクショナリ内のキーを持つリソースとして既にインスタンス化されているスタイルへの参照が返されます。

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

リソースは、WPF または XAML によって実現されるマークアップ拡張機能の使用方法の 1 つにすぎません。マークアップ拡張機能のリファレンス情報については、「WPF 名前空間の XAML 拡張機能」または「XAML 名前空間 (x:) 言語機能」を参照してください。マークアップ拡張機能の詳細については、「マークアップ拡張機能と XAML」を参照してください。

型コンバータによって実現される属性値

「属性構文」で説明したように、属性値は文字列で設定できる必要があります。文字列から他のオブジェクト型やプリミティブ値への変換という基本的なネイティブの処理は、String 型自体に基づいて行われます。しかし、多くの WPF 型やそのメンバでは、基本的な文字列属性の処理動作を拡張して、より複雑なオブジェクト型のインスタンスを文字列で属性値として指定できるようにしています。この処理は、コード レベルでは、文字列属性値を処理する CLR 型コンバータを指定することによって実現されます。たとえば、Margin などの四角形の領域の測定値を示すためによく使用される Thickness 構造体型は、この型を受け取るすべてのプロパティに対して、型コンバータによって実現される特殊な属性構文を公開します。これにより、XAML マークアップでこの型を簡単に使用できます。次の例では、型コンバータによって実現される属性構文を使用して Margin の値を指定しています。

<Button Margin="10,20,10,30" Content="Click me"/>

この属性構文の例は、次の例に示すより冗長な構文と同等です。次の例では、Thickness オブジェクト要素を含むプロパティ要素構文によって Margin が設定されています。Thickness の 4 つの主要なプロパティは、新しいインスタンスの属性として設定されています。

<Button Content="Click me">
  <Button.Margin>
    <Thickness Left="10" Top="20" Right="10" Bottom="30"/>
  </Button.Margin>
</Button>

型コンバータによって実現される構文を使用するか、より冗長な同等の構文を使用するかは、通常はコーディング スタイル上の選択になりますが、型コンバータによって実現される構文を使用した方がマークアップが簡潔になります (ただし、一部の少数のオブジェクトの場合は、型オブジェクト自体に既定のコンストラクタがないため、プロパティをその型に設定するには型コンバータを使用する以外方法がありません。Cursor はその一例です)。

型コンバータによって実現される属性構文がサポートされるしくみの詳細については、「TypeConverters および XAML」を参照してください。

コレクション型と XAML コレクション プロパティ

XAML では、コレクション型を表すオブジェクト要素を意図的にマークアップから省略できる言語機能が規定されています。コレクション型を受け取るプロパティが XAML プロセッサによって処理されると、そのコレクションのオブジェクト要素がマークアップ内に存在していなくても、適切なコレクション型のインスタンスが暗黙的に作成されます。SDK のコレクション型のリファレンス ページでは、このようにコレクションのオブジェクト要素を意図的に省略する構文が "暗黙的なコレクション構文" として XAML 構文セクションに示されている場合があります。

暗黙的なコレクション構文は、IList または IDictionary を実装する型や、配列で使用できます。

暗黙的なコレクション構文の例は、特に言及しませんでしたが、XAML リソースの例で既に見ました。

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

ルート要素は別として、ページ上で他の要素の子要素として入れ子になっているすべてのオブジェクト要素は、実際には、その親要素の暗黙的なコレクション プロパティのメンバか、親要素の XAML コンテンツ プロパティ (XAML コンテンツ プロパティについては後で説明) の値を指定する要素か、またはその両方です。つまり、マークアップ ページ内の親要素と子要素の関係は、実際にはルートにある単一のオブジェクトであり、ルートの下のすべてのオブジェクト要素は、親のプロパティ値を指定する単一のインスタンスか、親のコレクション型のプロパティ値でもあるコレクション内の項目の 1 つです。リソースの例の場合、Resources プロパティは ResourceDictionary 型のオブジェクトを受け取ります。ResourceDictionary のオブジェクト要素を明示的に指定した同等の構文を次の例に示します。

<Page.Resources>
  <ResourceDictionary>
      <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
      <Style TargetType="Border" x:Key="PageBackground">
        <Setter Property="Background" Value="Blue"/>
      </Style>


...


  </ResourceDictionary>
</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


    </Border>
  </StackPanel>
</Page>

Resources コレクションは、多くの一般的な WPF フレームワーク レベル要素に存在するコレクション プロパティの 1 つです。このプロパティを XAML で設定するには、プロパティ要素構文を使用する必要があります。プロパティ要素で囲まれた各オブジェクト要素がコレクションの項目 (IDictionary の実装) になります。通常は、項目を含むプロパティ (インデクサ) がコレクション型自体にありますが、そのプロパティをマークアップで指定することはできません。そのプロパティは完全に暗黙的です。ResourceDictionary の場合、そのプロパティは Item インデクサです。

リソース ディクショナリの使用方法の詳細な例については、「方法 : リソースを定義および参照する」を参照してください。

XAML コンテンツ プロパティ

XAML で規定されている言語機能として、XAML オブジェクト要素として使用できるすべてのクラスで、そのプロパティのうちの 1 つだけをそのクラスのインスタンスの XAML コンテンツ プロパティとして指定できます。XAML コンテンツ プロパティを持つオブジェクト要素が XAML プロセッサによって処理されると、そのオブジェクト要素のすべての XML 子要素は、そのコンテンツ プロパティを表す暗黙的なプロパティ要素タグで囲まれているものとして処理されます。マークアップでは、XAML コンテンツ プロパティのプロパティ要素構文は省略できます。マークアップで指定するすべての子要素が XAML コンテンツ プロパティの値になります。

XAML コンテンツ プロパティの例は、特に言及しませんでしたが、このトピックの最初の例で既に見ました。

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

ここで、ButtonStackPanel の子要素です。この簡略化された直観的なマークアップでは、2 つのタグがそれぞれ異なる理由で省略されています。

  • StackPanel.Children プロパティ要素の省略 : StackPanelPanel から派生します。Panel は、Panel.Children をその XAML コンテンツ プロパティとして定義します。したがって、Panel のすべての派生クラスがその XAML コンテンツ プロパティを持ち、Panel.Children のプロパティ要素を省略できます。

  • UIElementCollection オブジェクト要素の省略 : Panel.Children プロパティは、IList を実装する UIElementCollection 型を受け取ります。この UIElementCollection オブジェクト要素のタグは、XAML で定義されているコレクションの規則に基づいて省略できます。この場合は、UIElementCollection をオブジェクト要素としてインスタンス化することはできません。このコレクション オブジェクトを明示的に宣言するという選択肢自体がありません。これは、UIElementCollection では既定のコンストラクタが公開されていないからです。コンストラクタが公開されていなくても、XAML コレクション構文の処理によって XAML で暗黙的に使用することができるため、オブジェクト要素の使用方法のためのコンストラクタが公開されていない WPF コレクション型はこのほかにもいくつかあります。上の例で UIElementCollection オブジェクト要素がコメント アウトされているのはこのためです。このコメントを解除するとコンパイルできなくなります。

<StackPanel>
  <StackPanel.Children>
    <!--<UIElementCollection>-->
    <Button>
      <Button.Content>
        Click Me
      </Button.Content>
    </Button>
    <!--</UIElementCollection>-->
  </StackPanel.Children>
</StackPanel>

内部テキストと XAML コンテンツ プロパティ

StackPanel / Button の例には、さらに別のバリエーションもあります。

<StackPanel>
  <Button>Click Me</Button>
</StackPanel>

Button の表示テキストの指定方法の違いに注目してください。前の例では属性構文で Content プロパティが指定されていましたが、ここでは表示文字列が Button オブジェクト要素内の内部テキストになっています。この構文が有効なのは、Content が、Button の基本クラスである ContentControl の XAML コンテンツ プロパティであるからです。要素内の文字列は、Content プロパティのプロパティ型に基づいて評価されます。このプロパティ型は、Object です。Object では文字列の型変換は試行されないため、Content プロパティの値はリテラル文字列値になります。または、Button 内のコンテンツを任意の単一の Object にするという方法もあります。Button などのコントロールでは、通常、XAML コンテンツ プロパティを UI と表示テキスト、コントロールの複合、またはその両方に使用できるようにクラスの XAML コンテンツ プロパティを定義します。

このように、要素内に文字列をコンテンツとして配置して他の一般的なマークアップ言語に似たマークアップを生成できる機能は、フロー ドキュメント モデル (詳細については「Windows Presentation Foundation のドキュメント」を参照) とローカリゼーション (「Windows Presentation Foundation のグローバリゼーション」を参照) で特に重要になります。

XAML コンテンツ プロパティの値は連続している必要がある

XAML コンテンツ プロパティの値は、そのオブジェクト要素の他のすべてのプロパティ要素の前または後に指定されている必要があります。これは、XAML コンテンツ プロパティの値を文字列として指定する場合も、1 つ以上のオブジェクトとして指定する場合も同様です。たとえば、次のマークアップはコンパイルされません。

<Button>I am a 
  <Button.Background>Blue</Button.Background>
  blue button</Button>

これが無効なのは、コンテンツ プロパティに対してプロパティ要素構文を使用して明示的な構文にした場合、次のように、コンテンツ プロパティが 2 回設定されることになるからです。

<Button>
  <Button.Content>I am a </Button.Content>
  <Button.Background>Blue</Button.Background>
  <Button.Content> blue button</Button.Content>
</Button>

コンテンツ プロパティがコレクションで、子要素内にプロパティ要素が混在している場合も、同様に無効です。

<StackPanel>
  <Button>This example</Button>
  <StackPanel.Resources>
    <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
  </StackPanel.Resources>
  <Button>... is illegal XAML</Button>
</StackPanel>

コンテンツ モデル

あるクラスが構文の点で XAML 要素として使用できても、その要素がアプリケーションやページで正しく機能するためには、全体的なコンテンツ モデルや要素ツリーの適切な位置に配置されている必要があります。たとえば、MenuItem は、通常、MenuBase 派生クラス (Menu など) の子としてのみ配置されている必要があります。特定の要素のコンテンツ モデルについては、XAML 要素として使用できるコントロールやその他の WPF クラスのクラス ページの解説を参照してください。複雑なコンテンツ モデルを持つ一部のコントロールについては、コンテンツ モデルの概念に関するトピックを参照してください。「コンテンツ モデル」を参照してください。

XAML の大文字/小文字と空白

XAML は大文字と小文字を区別します。アセンブリ内の基になる型や型のメンバとの名前による比較の際には、すべてのオブジェクト要素、プロパティ要素、および属性名を、大文字と小文字を正しく区別して指定する必要があります。属性の値については、大文字と小文字が区別されない場合もあります。値の大文字と小文字が区別されるかどうかは、その値を受け取るプロパティ (そのプロパティの値型) に関連付けられている型コンバータの動作によって決まります。たとえば、Boolean 型を受け取るプロパティでは、true と True の両方を同じ値として受け取ることができますが、これは、Boolean の既定の文字列の型変換で、これらを同じ値として扱うことが許可済みであるためです。

XAML プロセッサとシリアライザでは、意味のない空白はすべて無視 (省略) され、意味のある空白は正規化されます。この動作は、通常、XAML コンテンツ プロパティ内に文字列を指定した場合にのみ行われます。簡単に言うと、XAML では、空白、ラインフィード、およびタブ文字が空白に変換され、連続する文字列の両端では、空白があればそれぞれ 1 つ保持されます。XAML の空白の処理の詳細は、このトピックの範囲を超えています。詳細については、「XAML での空白の処理」を参照してください。

XAML 構文の詳細

暗黙的なコレクション構文と XAML コンテンツ プロパティは、どちらも、特定の暗黙的なタグの省略を実現する XAML 言語の機能です。これらの機能は、マークアップを作成したり検査する際にページ上の要素の親子のリレーションシップをわかりやすくすることを目的としています。

この SDK ドキュメント全体で、属性構文とプロパティ要素構文の詳細、および XAML 構文を説明するために使用されているその他の用語の詳細については、「XAML 構文用語」を参照してください。カスタム クラス作成時に XAML の使用を有効にすることを検討している場合は、トピック「XAML 構文用語」を参照することもお勧めします。

XAML ルート要素と XML 名前空間

XAML ファイルを正しい形式の XML ファイルにし、有効な XAML ファイルにするためには、ルート要素を 1 つだけ指定する必要があります。通常は、アプリケーション モデルの一部である要素を選択します (ページの場合は WindowPage、外部ディクショナリの場合は ResourceDictionary、アプリケーション定義のルートの場合は Application など)。WPF ページの一般的な XAML ファイルの Page というルート要素の例を次に示します。

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"


...


</Page>

このルート要素には、xmlns と xmlns:x という属性も含まれています。これらの属性は、マークアップで参照する要素の要素定義が含まれている XML 名前空間を XAML プロセッサに対して示します。xmlns 属性は既定の XML 名前空間を明示的に指定しています。既定の XML 名前空間内では、マークアップのオブジェクト要素をプレフィックスなしで指定できます。WPF アプリケーションのほとんどのシナリオ (およびこの SDK の WPF セクションのほとんどすべての例) で、既定の XML 名前空間は WPF 名前空間 https://schemas.microsoft.com/winfx/2006/xaml/presentation にマッピングされます。xmlns:x 属性は、XAML 言語の名前空間 https://schemas.microsoft.com/winfx/2006/xaml をマッピングする追加の XML 名前空間を指定しています。XAML 仕様で定義されている必要な言語コンポーネントには、このマッピングを含むファイルのマークアップで参照する場合、x: というプレフィックスを付けます。このように xmlns を使用して使用方法とマッピングのスコープを定義することは、XML 1.0 仕様に一致しています。xmlns 属性が厳密に必要とされるのは、各ページのルート要素、およびマークアップで指定されているアプリケーション定義だけです。xmlns の定義はルートのすべての子要素に適用されます (この動作も xmlns の XML 1.0 仕様に一致しています)。xmlns 属性をルートの下のその他の要素で定義することも可能で、その場合も、定義されている要素のすべての子要素に適用されます。ただし、この使用方法は一般的ではありません。XML 名前空間を頻繁に定義したり再定義したりすると、XAML のマークアップが読みにくくなるためです。

WPF アセンブリは、プロジェクト ビルド ファイルに含まれている構成により、WPF から既定の XML 名前空間へのマッピングをサポートする型を含んでいることが認識されます。またアセンブリは、ターゲット ファイルでもマッピングされています。このため、WPF アセンブリに基づく XAML 要素を参照するには、xmlns をマッピングするだけで済みます。独自のカスタム アセンブリや、WPF 外のアセンブリに対しては、xmlns のマッピングの一部として、そのアセンブリを指定できます。通常は異なるプレフィックスを選択しますが、異なる XML 名前空間を既定にしてから WPF をプレフィックスにマッピングすることもできます。XML 名前空間とアセンブリ内の対応するコードの名前空間との関連の詳細については、「XAML 名前空間および名前空間の割り当て」を参照してください。

x: プレフィックス

前のルート要素の例では、XAML の XML 名前空間である https://schemas.microsoft.com/winfx/2006/xaml をマッピングするために x: というプレフィックスが使用されています。この x: プレフィックスは、この SDK 全体を通じて、プロジェクトのテンプレート、例、およびドキュメントで、XAML XML 名前空間をマッピングするために使用されます。x: プレフィックス/XAML XML 名前空間には、XAML で頻繁に使用されるプログラミング構成要素がいくつかあります。x: プレフィックス/XAML 名前空間のプログラミング構成要素の中で最もよく使用されるものを以下に示します。

  • x:Key: ResourceDictionary 内の各リソースに一意のキーを設定します。一般に、アプリケーションのマークアップにおいて、x:Key が x: の使用の約 90% を占めます。

  • x:Class: XAML ページの分離コードを提供するクラスの CLR 名前空間とクラス名を指定します。分離コードをサポートするにはこのようなクラスが必要であり、これはリソースがない場合でもほぼ常に x: がマッピングされるためです。

  • x:Name: オブジェクト要素が処理された後のランタイム コードに存在するインスタンスのランタイム オブジェクト名を指定します。x:Name は、同等の WPF フレームワーク レベルの Name プロパティがサポートされない要素に名前を指定する場合に使用します。一部のアニメーション シナリオでこのような状況があります。

  • x:Static: 他の方法では XAML で互換性のないプロパティである静的な値を取得する値参照を可能にします。

  • x:Type: 型の名前に基づいて Type の参照を作成します。これは、Style.TargetType など、Type を受け取る属性を指定する場合に使用します。ただし、多くの場合、プロパティには文字列から Type へのネイティブ変換が用意されていて、x:Type の使用は省略可能です。

x: プレフィックス/XAML 名前空間には、これ以外にも、あまり一般的でないプログラミング構成要素があります。詳細については、「XAML 名前空間 (x:) 言語機能」を参照してください。

イベントと XAML 分離コード

ほとんどの WPF アプリケーションは、マークアップと分離コードの両方で構成されています。1 つのプロジェクトの中で、XAML を使用して .xaml ファイルとして作成され、CLR 言語 (Microsoft Visual Basic .NET や C# など) を使用して分離コード ファイルが作成されます。名前空間とクラスを XAML ページのルート要素の x:Class 属性として指定することにより、XAML ファイルがコンパイルされるときに、各 XAML ページの XAML 分離コード ファイルの場所が特定されます。

これまでに見てきた例にはいくつかのボタンが含まれていましたが、それらのボタンにはまだ論理的な動作が関連付けられていません。オブジェクト要素の動作を追加するためのアプリケーション レベルの主要なメカニズムでは、要素クラスの既存のイベントを使用して、そのイベントの特定のハンドラを作成します。実行時にそのイベントが発生すると、そのハンドラが呼び出されます。イベントの名前と使用するハンドラの名前をマークアップで指定し、ハンドラを実装するコードは分離コードで定義します。

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyNamespace.MyPageCode">
  <Button Click="ClickHandler" >Click Me!</Button>
</Page>
namespace MyNamespace
{
  public partial class MyPageCode
  {
    void ClickHandler(object sender, RoutedEventArgs e)
    {
      Button b = e.Source as Button;
      b.Background = Brushes.Red;
    }
  }
}

この分離コード ファイルでは、CLR 名前空間 MyNamespace が使用されており、その名前空間内の部分クラスとして MyPageCode が宣言されています。これは、マークアップのルートで指定されている x:Class 属性値 MyNamespace.MyPageCode に対応しています。コンパイラは、ルート要素の型からクラスを派生させることにより、コンパイルされた XAML ページの部分クラスを自動的に作成します。同じ部分クラスを定義する分離コードを指定した場合、作成されるコードは、コンパイルされたアプリケーションの同じ名前空間とクラスに結合されます。

分離コード プログラミングの要件の詳細については、「分離コードと XAML」の「分離コード、イベント ハンドラ、および部分クラスの要件」を参照してください。

独立した分離コード ファイルが作成されるのを避ける場合は、XAML ファイル内にコードをインラインで埋め込むこともできます。ただし、インライン コードには多くの制限があり、汎用性の面で劣ります。詳細については、「分離コードと XAML」を参照してください。

イベント属性構文

イベントによる動作をマークアップで指定する場合、通常は、属性構文を使用してハンドラをアタッチします。イベント属性を指定したオブジェクト要素は、イベントをリッスンしてハンドラを呼び出すインスタンスになります。属性名は、処理する特定のイベントの名前です。属性値は、定義するハンドラのメソッド名です。その後、そのイベントのデリゲートに基づくハンドラの実装を分離コードで指定します。分離コード内のハンドラは、Microsoft Visual Basic .NET、C# などのプログラミング言語で作成します。

イベントが発生すると、各 WPF イベントはイベント データを報告します。このイベント データにイベント ハンドラでアクセスできます。前の例のハンドラは、報告されているイベント ソースをイベント データを通じて取得して、そのソースのプロパティを設定しています。

ルーティング イベント

ルーティング イベントは、WPF に固有の基本的なイベント機能です。ルーティング イベントを使用すると、要素ツリー リレーションシップでつながっている要素間において、ある要素で発生したイベントを別の要素で処理できます。XAML 属性を使用してイベント処理を指定する際には、要素のクラス メンバ テーブルにその特定のイベントが含まれているかどうかに関係なく、任意の要素でルーティング イベントをリッスンおよび処理できます。これを実現するには、所有するクラスの名前でイベント名属性を修飾します。たとえば、ここで使用している StackPanel / Button の例の親 StackPanel で子要素ボタンの Click イベントのハンドラを登録するには、StackPanel オブジェクト要素で属性 Button.Click を指定します。属性値は、使用するハンドラの名前です。詳細については、「ルーティング イベントの概要」を参照してください。

x:Name

オブジェクト要素を処理することによって作成されたオブジェクト インスタンスには、既定では一意の識別子や、コードで使用できる固有のオブジェクト参照はありません。コードでコンストラクタを呼び出す場合、通常は、コンストラクタの結果を使用して、作成されたインスタンスに変数を設定することにより、そのインスタンスを後からコードで参照できるようにします。XAML では、マークアップ定義によって作成されたオブジェクトに標準的なアクセスを行うことができるようにするために、x:Name 属性が定義されています。x:Name 属性の値は、任意のオブジェクト要素で設定できます。分離コードでは、選択した識別子は、作成されたインスタンスを参照するインスタンス変数と同じ意味を持ちます。名前付きの要素はあらゆる点でオブジェクト インスタンスのように機能するため (名前で対象のインスタンスが参照されます)、名前付きの要素を分離コードで参照してアプリケーション内の実行時のやり取りを処理できます。

WPF フレームワーク レベルの XAML 要素は、Name プロパティを継承します。このプロパティは、XAML で定義されている x:Name 属性と同等です。その他のクラスでも、x:Name と同等のプロパティが用意されている場合があり、そのようなプロパティも通常は Name プロパティとして定義されています。一般に、目的の要素のメンバ テーブルに Name プロパティがない場合は、代わりに x:Name を使用します。

次の例では、StackPanel 要素の Name を設定しています。その後、その StackPanel 内の Button のハンドラで、Name で設定したインスタンス参照 buttonContainer を使用して StackPanel を参照しています。

<StackPanel Name="buttonContainer">


...


  <Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>
void RemoveThis(object sender, RoutedEventArgs e)
{
    FrameworkElement fe = e.Source as FrameworkElement;
    if (buttonContainer.Children.Contains(fe))
    {
        buttonContainer.Children.Remove(fe);
    }
}

変数と同様に、インスタンスの名前も、予測可能な特定のスコープ内において名前が一意になるように、スコープの概念によって制御されています。ページを定義するプライマリ マークアップで一意の名前スコープが指定され、名前スコープの境界はそのページのルート要素になります。ただし、実行時には、スタイルやスタイル内のテンプレートなどの他のマークアップ ソースもページとやり取りでき、そのようなマークアップ ソースそれぞれの名前スコープはページの名前スコープと必ずしも関連していません。x:Name および名前スコープの詳細については、「Name」、「x:Name 属性」、または「WPF 名前スコープ」を参照してください。

添付プロパティと添付イベント

XAML で規定されている言語機能では、要素のメンバ テーブルに存在するかどうかに関係なく、特定のプロパティやイベントを任意の要素で指定することができます。この機能は、プロパティでは添付プロパティ、イベントでは添付イベントと呼びます。添付プロパティと添付イベントは、概念的には、クラス階層と関係なく任意の要素/クラスに設定できるグローバル メンバと考えることができます。

XAML の添付プロパティは、通常、属性構文で使用されます。属性構文では、OwnerType.PropertyName という形式で添付プロパティを指定します。この形式は、表面的にはプロパティ要素の使用方法に似ていますが、ここで指定する OwnerType は常に、添付プロパティが設定されるオブジェクト要素とは別の型です。OwnerType は、XAML プロセッサで添付プロパティの値を取得したり設定したりするために必要なアクセサ メソッドを提供する型です。添付プロパティのシナリオとしては、子要素が親要素にプロパティ値を報告できるようにするために使用されるのが最も一般的です。

DockPanel.Dock 添付プロパティの例を次に示します。DockPanel クラスは、DockPanel.Dock のアクセサを定義しています。したがって、この添付プロパティを所有しています。DockPanel クラスには、子要素を反復処理して各要素で DockPanel.Dock の設定値がないかどうかをチェックするロジックも含まれています。値が見つかった場合は、レイアウト時に子要素を配置するために使用されます。実際、DockPanel クラスは、DockPanel.Dock 添付プロパティとこの配置の機能のために使用されます。

<DockPanel>
  <Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
  <Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>

Windows Presentation Foundation (WPF) では、すべての添付プロパティは依存関係プロパティとしても実装されます。詳細については、「添付プロパティの概要」を参照してください。

添付イベントも、OwnerType.EventName という同じような形式の属性構文を使用します。他のイベントの場合と同様に、XAML の添付イベントの属性値では、要素でイベントが処理されるときに呼び出されるハンドラ メソッドの名前を指定します。 

添付イベントは、たとえば、任意の要素で処理できるデバイス入力イベント (マウス ボタンなど) に対して使用されます。そうした添付イベントの 1 つの例は、Mouse.MouseDown です。ただし、WPF フレームワーク レベルのほとんどの要素では、添付イベントを使用しなくてもこのイベントを利用できます。これは、基本要素クラス UIElement が、Mouse.MouseDown 添付イベントのエイリアスを作成して、そのエイリアスを UIElement のメンバ テーブルで (MouseDown として) 公開しているためです。結果として、通常、XAML ページや Windows Presentation Foundation (WPF) アプリケーションのプログラミングで添付イベント構文を指定する必要はありません。この例外となるのは、カスタム要素を使用する場合や、UIElement から派生していないがビジュアル表現を持つオブジェクト要素 (こうした要素はまれです) を使用する場合です。WPF では、すべての添付イベントはルーティング イベントとしても実装されます。ContentElement でも、フロー ドキュメント モデルで使用するための入力イベントのエイリアスが公開されます。詳細については、「ルーティング イベントの概要」および「入力の概要」を参照してください。

XAML ページのルート要素の構造

次の表は、一般的な XAML ページのルート要素の構造を示しています。このトピックで取り上げたルート要素に特有の属性が含まれています。

<Page

ルート要素の開始オブジェクト要素。

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

既定の (WPF) 名前空間。

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

XAML 名前空間。

x:Class="MyNamespace.MyPageCode"

部分クラス宣言。同じ部分クラスに定義されている分離コードにマークアップを関連付けます。

>

ルートのオブジェクト要素の終了。ページに子要素が含まれているため、まだ閉じられていません。

基本クラスと XAML

XAML とそのスキーマの基礎になっているのは、CLR オブジェクトに対応する一連のクラスです。これらのクラスは、XAML で使用されるマークアップ要素にも対応しています。ただし、すべてのクラスを要素にマッピングできるわけではありません。CLR オブジェクト モデルで継承のために使用される ButtonBase などの抽象クラスや一部の非抽象基本クラスでは、対応する XAML マークアップ タグはサポートされません。それでも基本クラスは、抽象クラスも含め、XAML 開発にとって重要です。これは、XAML の各具象要素は、その階層構造内の基本クラスのメンバを継承するためです。それらのメンバには、多くの場合、要素の属性として設定できるプロパティや、処理できるイベントが含まれています。FrameworkElement は、WPF フレームワーク レベルにおける WPF の具象基本UI クラスです。UI をデザインする際には、さまざまな図形、パネル、デコレータ、コントロールのクラスを使用しますが、それらはすべて FrameworkElement から派生します。関連する基本クラスの FrameworkContentElement は、FrameworkElement の API を意図的に反映する API を使用して、フロー レイアウトのプレゼンテーションに適したドキュメント指向の要素をサポートします。要素レベルの属性と CLR オブジェクト モデルの組み合わせにより、一連の一般的なプロパティをほとんどの具象 XAML 要素で、厳密な要素型や基になるクラスに関係なく設定できるようになっています。

XAML のセキュリティ

XAML は、オブジェクトのインスタンス化と実行を直接表現するマークアップ言語です。したがって、XAML で作成された要素では、対応する生成コードと同じシステム リソースとのやり取り (ネットワーク アクセスやファイル システムの入出力など) が可能です。

WPF は、.NET セキュリティ フレームワークのコード アクセス セキュリティ (CAS) をサポートしています。このため、インターネット ゾーンで実行される WPF コンテンツは、実行のアクセス許可を制限されます。"Loose XAML" (読み込み時に XAML ビューアによって解釈されるコンパイルされない XAML のページ) と XAML ブラウザ アプリケーション (XBAP) は、通常このインターネット ゾーンで実行され、同じアクセス許可セットを使用します。ただし、完全に信頼されたアプリケーションに読み込まれた XAML は、システム リソースに対してホスト アプリケーションと同じアクセス権を持ちます。詳細については、「Windows Presentation Foundation 部分信頼セキュリティ」を参照してください。

コードからの XAML の読み込み

XAML を使用して UI 全体を定義することもできますが、UI の一部のみを XAML で定義することが適切である場合もあります。この機能を利用すると、部分的なカスタマイズ、情報のローカル保存、XAML を使用したビジネス オブジェクトの提供など、さまざまなシナリオが可能になります。このようなシナリオで重要になるのは、XamlReader クラスおよびその Load メソッドです。XAML ファイルを入力とし、そのマークアップから作成された実行時のオブジェクト ツリー全体を表す 1 つのオブジェクトが出力となります。このオブジェクトを、アプリケーション内に既に存在する別のオブジェクトのプロパティとして挿入できます。そのプロパティが、最終的な表示機能を備え、アプリケーションへの新しいコンテンツの追加を実行エンジンに通知するコンテンツ モデルにおける適切なプロパティである場合、XAML を使用して、実行中のアプリケーションのコンテンツを非常に簡単に修正できます。ただし、実行中のアプリケーションにファイルを読み込むことは明らかにセキュリティに影響するので、この機能を利用できるのは、一般に完全信頼アプリケーションの場合のみです。

次の内容

このトピックでは、XAML 構文の概念と用語の基本的な概要を紹介しました。ここで使用した用語の詳細については、「XAML 構文用語」を参照してください。

まだ終えていない場合は、「Windows Presentation Foundation の概要」のチュートリアルに挑戦してみることをお勧めします。このチュートリアルで説明されているマークアップ アプリケーションを実際に作成すると、ここで説明した多くの概念の理解が深まります。

WPF は、Application クラスに基づく特有のアプリケーション モデルを使用します。詳細については、「アプリケーション管理の概要」を参照してください。

XAML を含むアプリケーションをコマンド ラインから作成する方法、および Microsoft Visual Studio を使用して作成する方法の詳細については、「WPF アプリケーション (WPF) のビルド」を参照してください。

Windows Presentation Foundation (WPF) のプロパティの汎用性についての詳細、および依存関係プロパティの概念の概要については、「依存関係プロパティの概要」を参照してください。

最後に、XAMLPad という XAML 編集ツールが SDK に用意されています。このツールを使用して、XAML をリアルタイムで試してみることができます。

参照

概念

XAMLPad

XAML およびカスタム クラス

基本要素の概要

WPF のツリー

その他の技術情報

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

WPF 名前空間の XAML 拡張機能

コンテンツ モデル