エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 の XAML

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

ここでは、Windows Phone で使用される XAML (Extensible Application Markup Language) でオブジェクトの宣言やプロパティの設定を行うためのさまざまな方法について説明します。

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

XAML (Extensible Application Markup Language) は宣言型言語の一種です。具体的には、XAML では、複数のオブジェクトの間の階層的な関係を示す言語構造と、型の拡張をサポートするバッキング型変換を使用して、オブジェクトの初期化およびオブジェクトのプロパティの設定を行うことができます。表示される UI 要素を宣言型 XAML マークアップで作成できます。さらに、別の分離コード ファイルを使用して、イベントに応答することも、XAML で宣言したオブジェクトを操作することもできます。XAML 言語では、開発プロセスで使用されるさまざまなツールとロールの間で、情報を損なわずにソースを交換することがサポートされます。たとえば、Visual Studio と Microsoft Expression Blend との間で XAML ソースを交換することができます。

XAML ファイルとは、一般にファイル名拡張子が .xaml の XML ファイルのことです。次の例は、基本的な Windows Phone XAML ファイルの内容を示しています。

<UserControl x:Class="MyWindowsPhone.Page"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
>
  <Grid Background="OldLace">
  </Grid>
</UserControl>

XAML は、Windows Phone アーキテクチャおよび Windows Phone アプリの開発プロセスにおいて重要な役割を果たします。

  • XAML は、Windows Phone UI と UI 内の要素を宣言するための基本形式です。一般的には、プロジェクトの 1 つ以上の XAML ファイルが、アプリの初期表示される UI の "ページ" メタファを表します。また、別の XAML ファイルで、ナビゲーション用 UI またはモーダル置換 UI のための追加のページを宣言できます。それ以外の XAML ファイルでは、リソース (テンプレートなど、再利用または置き換えが可能なアプリのその他の要素) を宣言できます。

  • XAML は、Windows Phone コントロールおよび UI の論理的な基礎に適用されるスタイルおよびテンプレートを宣言するために使用される形式です。既存のコントロールをテンプレート化する場合や、コントロール作成者としてコントロールの既定のテンプレートを提供する場合などに、このような操作を行います。スタイルとテンプレートの定義に使用する場合、通常、XAML は ResourceDictionary ルートを使用して XAML ファイルとして宣言されます。

  • XAML は、Windows Phone UI を作成し、異なるデザイナー アプリ間で UI 設計を交換することを可能にするデザイナー サポートの共通形式です。注目すべき点は、Windows Phone アプリ用の XAML を、Expression Blend 製品と Visual Studio との間で入れ替えることができる点です。

  • Windows Phone の XAML で UI の外観を定義し、関連付けられた分離コード ファイルでロジックを定義します。UI 設計は、分離コードのロジックに変更を加えることなく調整できます。XAML は、この役割において、主にビジュアル デザインに責任を負う担当者とアプリ ロジックおよび情報設計の責任者との間のワークフローを簡素化します。

  • ビジュアルなデザイナーとデザイン画面のサポートにより、XAML は、開発の初期段階での迅速な UI のプロトタイピングをサポートします。さらに、ビジュアル デザインが大幅に変更された場合でも、設計の要素を開発プロセス全体でコード アクセス ポイントとして保持できる可能性が高まります。

開発プロセスにおける役割によっては、XAML 言語または XAML 構文を広く使用する機会がない場合があります。Windows Phone の XAML と対話する度合いは、使用している開発環境、ツールボックスやプロパティ エディターなどの対話型のデザイン環境機能を使用しているかどうか、および Windows Phone アプリの範囲と目的によっても異なります。ただし、Windows Phone アプリの開発時には、テキスト ベースのエディターを使用して要素レベルで Windows Phone の XAML ファイルの編集を行います。このトピックは、XAML 言語および XAML 構文の詳細を示すことを目的としています。さらに、このトピックでは、XAML を使用する他のフレームワーク (WPF、WCF など) では利用できない、Windows Phone に固有の XAML の使用法および動作についても説明します。ここに示された情報を理解することで、Windows Phone 用 XAML コードのテキスト表現を正確に編集できるようになります。さらに、XAML ファイルがツール、マークアップのコンパイル処理、または Windows Phone ランタイムでのアプリの読み込みによって使用される際に、XAML ファイルの宣言および目的の妥当性を保持することができます。

名前空間は、プログラミング上の広い定義において、プログラミング エンティティを参照する文字列トークンをどのように解釈するかを決定します。また、名前空間は、文字列トークンが再利用された場合にあいまいさを解決することもできます。名前空間の概念を取り入れることで、プログラミング フレームワークでユーザーによって宣言されたトークンとフレームワークによって宣言されたトークンを切り離すことや、名前空間の修飾により潜在的なトークンのクラッシュを明確化することなどができます。XAML 名前空間は、XAML 言語においてこの目的を果たす名前空間の概念です。XAML は、一般用と Windows Phone 用の両方の用途において、オブジェクト、オブジェクトのプロパティ、および階層として表されるオブジェクトとプロパティの関係を宣言するために使用されます。宣言するオブジェクトは、タイプ ライブラリによってサポートされます。次のいずれかのライブラリを使用できます。

  • 配布されたランタイムに含まれる Windows Phone コア ライブラリ。

  • Windows Phone SDK の一部として配布され、アプリ パッケージに含めて再配布するライブラリ (アプリ ライブラリ キャッシュのオプションを使用する場合もあります)。

  • アプリに組み込まれ、アプリ パッケージとして再配布される、サード パーティ コントロールの定義を表すライブラリ。

  • Windows Phone プロジェクトにより作成され、アプリの Windows Phone ユーザー コードの一部または全部を保持する独自のライブラリ。

  • 別のプロジェクトで定義し、いずれかの Web 配置ストラテジを使用して Windows Phone アプリ モデルを介して参照される、別のライブラリ。

XAML 名前空間の概念では、マークアップ内の XML 形式の名前空間宣言 (xmlns) を使用して、バッキング型情報を特定の XAML 名前空間に関連付けます。XAML 名前空間の識別子は URI でも、CLR 名前空間形式の文字列トークンとアセンブリ情報でも構いません。これにより、XAML ファイルを読み取る XAML プロセッサは、マークアップ内のトークンを判別でき、ランタイム オブジェクト表現を作成するときに XAML 名前空間に関連付けられているバッキング アセンブリから型およびメンバーを検索できます。

ほとんどの場合、XAML ファイルでは、既定の XAML 名前空間をルート要素に定義します。既定の XAML 名前空間は、プレフィックスでそれ以上修飾することなく宣言できる要素を定義します。たとえば、要素 <Balloon /> を宣言した場合、Balloon という要素が既定の XAML 名前空間に存在し有効であることが想定されます。その一方、定義済みの既定の XAML 名前空間に Balloon が存在しない場合は、<party:Balloon /> のようにプレフィックスを使用して参照を修飾する必要があります。このプレフィックスは、エンティティが既定の名前空間とは異なる XAML 名前空間に存在すること、特に使用上の目的で XAML 名前空間がプレフィックス party にマップされていることを示します。

XAML 名前空間は、名前空間が宣言されている特定の要素に適用されるほか、XAML 構造においてこの要素に含まれるすべての要素に対しても適用されます。したがって、ほとんどの場合は、この継承の概念を利用するために、XAML 名前空間をルート要素で宣言します。

Windows Phone の既定の XAML 名前空間には、コア ライブラリ System.Windows.dll の Windows Phone によって定義されている型のほとんどすべてが含まれているので、XAML で宣言を行う場合に便利です。既定の XAML 名前空間では、CLR 名前空間の修飾を省略できます。これは、コード ファイルにおける using ステートメントまたは Imports ステートメントの利便性に似ています。一方で、既定の XAML 名前空間では複数の CLR 名前空間の型を包含できる点が異なります。たとえば、既定の Windows Phone XAML 名前空間を使用した場合、<Button />System.Windows.Controls.Button を参照し、<ImageBrush />System.Windows.Media.ImageBrush を参照します。これが可能になるのは、System.Windows.ControlsSystem.Windows.Media のどちらの CLR 名前空間も、コア ライブラリの構築方法が定義された宣言に従って、Windows Phone の既定の XAML 名前空間にマップされるためです。

通常、Windows Phone SDK の一部として配布される Windows Phone ライブラリの場合、XAML でそこに含まれる型を使用するためには、プレフィックスのマッピングが必要になります。

アセンブリを読み込むデザイナーが特定のプレフィックスを示すことができるように、SDK ライブラリには CLR の属性があります。Visual Studio では、プロジェクトによって既に参照されているすべてのアセンブリに関して、参照先アセンブリ内の CLR 属性を読み取るオート コンプリート機能を使用できます。この Visual Studio 機能では、使用できるすべての XAML 名前空間をドロップダウンとして表示するか、または推奨されるプレフィックスが特定のマッピングの選択肢を提案するヒントとして使用されます。

Windows Phone SDK アセンブリは、URI ベースの XAML 名前空間を定義します。これにより、複数のライブラリと、ライブラリ内の複数の CLR 名前空間で XAML 名前空間を共有できます。

Windows Phone コア ライブラリ以外のライブラリに含まれる型を参照するには、プレフィックスを使用して XAML 名前空間を宣言およびマップする必要があります。一般に、ライブラリが URI ベースの XAML 名前空間をサポートしていない場合、XAML のライブラリの型にアクセスするために必要な XAML 名前空間の宣言に、次の 3 つの情報が必要です。

  • プレフィックス。後続の XAML マークアップ内でこの XAML 名前空間を参照するために使用されるマークアップ トークンを定義します。

  • この XAML 名前空間の要素のバッキング型を定義するアセンブリ。XAML プロセッサが XAML 宣言に基づいてオブジェクトを作成するには、この名前空間にアクセスする必要があります。

  • このアセンブリ内の CLR 名前空間。

XAML 言語の XAML 名前空間。

ほぼすべての Windows Phone XAML ファイルで宣言される 1 つの XAML 名前空間が、XAML 言語で定義される要素に対応する XAML 名前空間です。慣例として、XAML 言語の XAML 名前空間はプレフィックス x: に関連付けられます。Windows Phone プロジェクトの既定のプロジェクト テンプレートおよびファイル テンプレートでは、既定の XAML 名前空間 (プレフィックスなし、xmlns= のみ) と XAML 言語の名前空間 (プレフィックス x:) の両方がルート要素の一部として必ず定義されます。たとえば、次のサンプル スニペットは、Windows Phone アプリの初期ページの、テンプレートを使用して作成された UserControl ルートです (開始タグのみを表し、以降は省略しています)。

<UserControl  
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
...>

x: プレフィックス/XAML 言語の XAML 名前空間には、Windows Phone XAML で頻繁に使用されるプログラミング構成要素がいくつか存在します。x: プレフィックス/XAML 名前空間の構成要素の中で最もよく使用されるものを以下に示します。

  • x:Key: ResourceDictionary 内の各リソースに一意のユーザー定義のキーを設定します。キーのトークン文字列は、StaticResource マークアップ拡張機能の引数として使用され、別に使用されている XAML からのリソースを取得します。

  • x:Class: XAML ページの分離コードを提供するクラスの CLR 名前空間とクラス名を指定し、Windows Phone アプリ モデルのマークアップ コンパイラのビルド アクションにより作成または加えられるクラスに名前を付けます。分離コードをサポートする場合や、RootVisual として初期化することをサポートする場合には、このようなクラスが必要です。このため、リソースがない場合でもほぼ常に x: を割り当て、x:Name は使用しません。

  • x:Name: XAML で定義されたオブジェクト要素が処理された後のランタイム コードに存在するインスタンスのランタイム オブジェクト名を指定します。x:Name は、より便利な FrameworkElement.Name プロパティがサポートされない特殊なケースで要素の名前を指定する目的で使用します。

XAML 言語の XAML 名前空間には、これ以外にも、あまり一般的でないプログラミング構成要素があります。

その他の XAML 名前空間

Windows Phone 用の XAML ファイルには、プレフィックス d: (デザイナー名前空間を示す) や、プレフィックス mc: (マークアップ互換性を示す) を定義しているものがあります。通常、これらのファイルは、ツールまたはプロセスの間での XAML の交換に関連するインフラストラクチャ サポートのために使用されます。一般的な Windows Phone XAML でこれらの名前空間の要素を扱う必要はありません。

互換上の理由から、Windows Phone XAML は別の URI ベースの名前空間 http://schemas.microsoft.com/client/2007 も、使用可能な既定の XAML 名前空間としてサポートしています。通常、Windows Phone アプリのプログラミングでは既定の XAML 名前空間として http://schemas.microsoft.com/winfx/2006/xaml/presentation を使用してください。現在のアプリに http://schemas.microsoft.com/client/2007 は使用しないでください。

XAML ファイルには、ルートとして機能する要素が常に 1 つあります。ルートは、ページなどのいくつかのプログラミング構造の概念上のルートとなるオブジェクトまたはアプリのランタイム定義全体のオブジェクト グラフを宣言します。

XAML 構文では、次の 3 つの方法を使用して XAML でオブジェクトを宣言できます。

  • オブジェクト要素構文を直接使用: 開始タグと終了タグを使用して、オブジェクトを XML 形式の要素として宣言します。この構文を使用して、ルート オブジェクトを宣言することも、プロパティ値を設定する入れ子になったオブジェクトを作成することもできます。

  • 属性構文を間接的に使用: インライン文字列値を使用してオブジェクトを宣言します。概念上は、これを使用してルート以外の任意のオブジェクトをインスタンス化できます。この構文は、プロパティ値を設定するときに使用できます。この方法では、XAML プロセッサの間接的な操作が行われます。この理由は、設定対象になっているプロパティ、プロパティの型システムの特性、および指定された文字列値に基づいて、新しいオブジェクトの作成方法を把握する手段が必要なためです。つまり、一般的には、該当する型またはプロパティで文字列入力を処理できる型コンバーターがサポートされるか、XAML パーサーによってネイティブ変換が有効になります。

  • マークアップ拡張機能の使用: マークアップ拡張機能の概念については、このトピックの以降のセクションで説明します。

ただし、特定の XAML ボキャブラリでオブジェクトの作成用にどの構文を使うかをいつも選択できるというわけではありません。ボキャブラリの一部のオブジェクトは、作成時にオブジェクト要素構文しか使用できません。最初にプロパティ値を設定しないと作成できないオブジェクトも少数あります。実際、オブジェクト要素構文または属性構文のどちらを使用しても作成できるというオブジェクトは、Windows Phone では比較的まれです。両方の構文形式を使用できる場合でも、どちらか一方の構文形式が主流であったり、シナリオでの使用に適していたりします。

オブジェクトをインスタンス化することと同等のオブジェクトの宣言に加え、XAML で既存のオブジェクトを参照するために使用できる方法はほかにもあります。これらのオブジェクトは、XAML の他の領域で定義します。また、プラットフォームとそのアプリケーションまたはプログラミング モデルの特定の動作を介してこれらのオブジェクトが暗黙的に存在する場合もあります。オブジェクト参照の使用の詳細については、このトピックの「マークアップ拡張機能」のセクションで説明します。

オブジェクト要素構文を使用したオブジェクトの宣言

オブジェクト要素構文を使用してオブジェクトを宣言するには、次のパターンを使用してタグを記述します。ここで、objectName は、インスタンス化する型の名前を表します。このドキュメントでは、オブジェクト要素の使用 (方法) という用語が頻繁に登場します。これは、オブジェクト要素構文でオブジェクトを作成する際に使用される特定のマークアップを簡略化した表現です。

<objectName>

</objectName>

次の例では、Canvas オブジェクトを宣言するためにオブジェクト要素を使用しています。

<Canvas>
</Canvas>

Canvas などの多くの Windows Phone オブジェクトには、他のオブジェクトを含めることができます。

<Canvas>
  <Rectangle>
  </Rectangle>
</Canvas>

オブジェクトに他のオブジェクトを含めない場合は、開始タグと終了タグのペアを使う代わりに、便宜的に (また、XML に対する XAML の全体的関連の一環として) 1 つの自己終了タグを使用してオブジェクト要素を宣言できます。たとえば、次に示す <Rectangle /> タグのようにします。

<Canvas>
  <Rectangle />
</Canvas>

属性構文を使用したオブジェクトの宣言

プロパティの値が文字列のような単なる言語プリミティブではない場合は、プロパティを設定するオブジェクトのインスタンス化と、新しいオブジェクトを定義する主要なプロパティの初期化を、属性構文を使用して行うことができます。この動作は、プロパティ設定に関連付けられているので、属性構文を使用してオブジェクトを宣言する方法や、1 つの構文ステップでプロパティを設定する方法については、以降のセクションを参照してください。

初期化テキスト

オブジェクトを宣言するとき、構造の初期値を提供する内部テキストも同時に宣言できる場合があります。XAML では、この手法および構文を初期化テキストと呼びます。概念的には、初期化テキストは、パラメーターを持つコンストラクターの呼び出しに似ていますが、内部の XAML パーサーの実装は、通常はリテラルとしてそれを行いません。

初期化テキストは、Windows Phone で一部の構造体の初期値を設定するために役立ちます。この手法は、この構造体の値を複数のターゲット プロパティで共有する目的でリソース ディクショナリ内に構造体インスタンスを作成する場合に使用します。一部の構造体では、属性構文を使用して構造体の値を設定することはできません。この問題が存在する構造体には、GridLengthColor があります。

オブジェクト要素構文を使用して宣言したオブジェクトのプロパティを設定できます。XAML では、複数の方法でプロパティを設定できます。

  • 属性構文を使用する。

  • プロパティ要素構文を使用する。

  • コンテンツ要素構文を使用する。

  • コレクション構文を使用する (通常は暗黙的なコレクション構文)。

このように XAML でオブジェクトのプロパティを設定する方法はいくつかありますが、オブジェクトの宣言の場合と同様に、特定のプロパティを設定する際にどの方法も使用できるというわけではありません。一部のプロパティでは、1 種類の方法しかサポートされません。一方、複数の方法をサポートするプロパティもあります。たとえば、コンテンツ要素構文をサポートしているプロパティで、より詳細な形式のプロパティ要素構文や代替の属性構文もサポートしている場合があります。これは、プロパティと、そのプロパティが使用するオブジェクト型の両方に応じて決まります。XAML 構文で使用可能な方法については、XAML で設定できる各プロパティのリファレンス ページにある、XAML の使用方法に関するセクションで説明されています。Windows Phone のオブジェクトのプロパティには、XAML では設定できず、コードを使ってのみ設定できるプロパティもあります。

読み取り専用プロパティは、XAML やコードでどの方法を使用しても設定できません。ただし、追加のメカニズムが機能している場合は除きます。これには、プロパティの内部表現に設定されるコンストラクター オーバーロードを呼び出す場合や、厳密にはプロパティ アクセサーでないメソッドを呼び出す場合のほか、計算対象プロパティを呼び出す場合が該当します。計算対象プロパティは、設定可能な他のプロパティの値のほか、そのプロパティ値に対するサービスまたは動作の影響に依存します。これらの機能は、依存関係プロパティ システムで使用できます。依存関係プロパティの詳細については、「Windows Phone 8 の依存関係プロパティ」を参照してください。

XAML のコレクション構文の場合、一見、読み取り専用のプロパティを設定しているかのように見えますが、実際は違います。詳細については、このトピックの「コレクション構文によるプロパティの設定」を参照してください。

属性構文によるプロパティの設定

次の構文を使用します。objectName はインスタンス化するオブジェクト、propertyName はそのオブジェクトに設定するプロパティの名前、propertyValue は設定する値をそれぞれ表します。

<objectName propertyName="propertyValue" .../>

-or-

<objectName propertyName="propertyValue">

...<!--element children -->

</objectName>

どちらかの構文で、オブジェクトを宣言し、そのオブジェクトのプロパティを設定できます。最初のサンプルは、1 つのマークアップ要素ですが、このマークアップの解析は、実際には XAML プロセッサで別々の手順で行われます。まず、オブジェクト要素があるので、新しい objectName オブジェクトをインスタンス化する必要があることがわかります。そのようなインスタンスが作成された後にのみ、そのインスタンスにインスタンス プロパティ propertyName を設定できます。

次の例では、4 つの属性の属性構文を使用して、Rectangle オブジェクトの NameWidthHeight、および Fill の各プロパティを設定しています。

<Rectangle Name="rectangle1" Width="100" Height="100" Fill="Blue" />

XAML パーサーがどのようにこのマークアップを解釈してオブジェクト ツリーを定義するかをコードで表すと、次のような擬似コードになります。

Rectangle rectangle1 = new Rectangle();

rectangle1.Width=100.0;

rectangle1.Height=100.0;

rectangle1.Fill = new SolidColorBrush(Colors.Blue);

最初の行では、既定のコンストラクターを呼び出しています。Name の値が、コンストラクターの結果を割り当てるインスタンス名として使用されています。

Name を除き、この擬似コードの 2 ~ 4 行目の割り当ての順序は不定です。XAML の規則では、XAML パーサーは、インスタンスが作成された後、これらのプロパティを任意の順序で設定できる必要があります。

プロパティ要素構文によるプロパティの設定

多くの Windows Phone プロパティは、プロパティ要素構文を使用して設定できます。プロパティ要素構文を使用するには、プロパティ要素値を "設定する" ためにオブジェクト要素の新しいインスタンスを指定できる必要があります。

プロパティ要素構文を使用するには、設定するプロパティに対応する XML 要素を作成します。このような要素の形式は <object.property> です。標準 XML の場合、この要素は、その名前にドットが含まれている要素と見なされます。しかし、XAML では、要素名に含まれるドットによって、その要素がプロパティ要素、つまり propertyobject のプロパティであることがわかります。

次の文法では、property は設定するプロパティの名前を表し、propertyValueAsObjectElement は新しいオブジェクト (このプロパティが想定する値の型のオブジェクト) を宣言する新しいオブジェクト要素を表します。

<object>

<object.property>

propertyValueAsObjectElement

</object.property>

</object>

次の例では、プロパティ要素構文を使用して、SolidColorBrush オブジェクト要素で Rectangle の塗りつぶしを設定しています(SolidColorBrush 内では、Color は、属性構文を使用して設定されます)。この XAML をレンダリングすると、属性構文を使用して Fill を設定した上記の XAML の例とまったく同じ結果になります。

<Rectangle
  Name="rectangle1"
  Width="100" 
  Height="100"
> 
  <Rectangle.Fill> 
    <SolidColorBrush Color="Blue"/> 
  </Rectangle.Fill>
</Rectangle>

XAML コンテンツ構文によるプロパティの設定

一部の Windows Phone 型では、XAML コンテンツ要素構文を有効にするプロパティが定義されています。XAML コンテンツ要素構文では、プロパティのプロパティ要素を省略して、所有する型のオブジェクト要素タグ内でコンテンツを設定することによってプロパティを設定できます。通常は、1 つまたは複数のオブジェクト要素をコンテンツとして使用します。これを、XAML コンテンツ構文と言います。XAML コンテンツ構文が利用できる場合、Windows Phone リファレンス ドキュメントでは、該当するプロパティの XAML の使用方法に関するセクションにこの構文が示されています。

たとえば、BorderChild プロパティのページには、プロパティ要素構文の代わりに、Border の単一オブジェクト Child 値を設定する XAML コンテンツ構文が示されています。この使用法に該当する例を次に示します。

<Border>
  <Button .../>
</Border>

XAML コンテンツ プロパティとして宣言されているプロパティで、プロパティの型が Object であるかまたは String である "柔軟な" オブジェクト モデルもサポートされている場合、XAML コンテンツ構文を使用して、純粋な文字列を開始オブジェクト タグと終了オブジェクト タグの間のコンテンツとして配置できます。たとえば、TextBlockText プロパティのページには、属性構文の代わりに XAML コンテンツ要素構文を使用して Text の文字列値を設定する XAML 構文が示されています。次の例は、この使用法に該当し、Text プロパティを明示的に指定することなく、TextBlockText プロパティを設定します。Text は、属性を使用したりオブジェクト要素を宣言したりするのではなく、XML でコンテンツまたは "内部テキスト" と見なされる要素を使用して設定されます。

<TextBlock>Hello!</TextBlock>

コレクション構文によるプロパティの設定

XAML のコレクション構文にはさまざまなバリエーションがあります。最初は、XAML で読み取り専用のコレクションのプロパティを "設定" しているかのように思えます。しかし、実際には、ここで XAML によって実現されているのは、既存のコレクションへの項目の追加です。XAML のサポートを実装する XAML 言語および XAML プロセッサは、この構文を有効にするためにバッキング コレクション型の規則に依存します。

通常、コレクション項目 (インデクサーまたは Items プロパティ) を保持するコレクション型のプロパティは、XAML 構文に存在しません。XAML からコレクションを使用して何か便利なことを行おうとするとき、本当に必要なのは、必ずしもプロパティではなく、メソッド (Add メソッド) です。Add メソッドの呼び出しは、前に説明した規則です。XAML プロセッサが XAML コレクション構文内に 1 つまたは複数のオブジェクト要素を見つけると、オブジェクト タギングを使用して各オブジェクトが作成され、次に、コレクションの Add メソッドの呼び出しによって、新しく作成された各オブジェクトが格納先のコレクションに宣言順に追加されます。

次の例は、構築可能な (実際のコレクションを XAML 内でオブジェクト要素として定義し、初期化できる) コレクション型を使用したコレクション プロパティを示しています。

<LinearGradientBrush>
  <LinearGradientBrush.GradientStops>
    <!-- Here the GradientStopCollection tag is specified. -->
    <GradientStopCollection>
      <GradientStop Offset="0.0" Color="Red" />
      <GradientStop Offset="1.0" Color="Blue" />
    </GradientStopCollection>
  </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

ただし、コレクションを受け取る Windows Phone プロパティでは、XAML パーサーが、コレクションが格納されているプロパティを基に、暗黙的にコレクションのバッキング型を判別します。したがって、コレクションそのもののオブジェクト要素は、次の例のように省略することができます。

<LinearGradientBrush>
  <LinearGradientBrush.GradientStops>
    <!-- no explicit new GradientStopCollection, parser knows how to find or create -->
    <GradientStop Offset="0.0" Color="Red" />
    <GradientStop Offset="1.0" Color="Blue" />
  </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

また、この例には、コレクションのプロパティが存在しますが、これも、クラスの XAML コンテンツ プロパティとして識別されます。前の例の GradientStops プロパティや、その他の多くの Windows Phone プロパティがこれに該当します。これらの構文では、プロパティ要素を省略することもできます。その結果のマークアップは、次のようになります。

<LinearGradientBrush>
  <GradientStop Offset="0.0" Color="Red" />
  <GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush>

このように、コレクション構文とコンテンツ構文とを組み合わせた記述は、パネル、ビュー、項目コントロールなどのコントロールを合成する場合に広く用いられます。たとえば、次の例は、StackPanel 内で 2 つの UI 要素を合成させる XAML を、明示的に記述したケースと、可能な限り単純化して表現したケースとを対比して示したものです。

<!--explicit tags, and UIElementCollection commented-->
<StackPanel>
  <StackPanel.Children>
    <!--UIElementCollection-->
    <TextBlock>Hello</TextBlock>
    <TextBlock>World</TextBlock>
    <!--/UIElementCollection-->
  </StackPanel.Children>
</StackPanel>

<!--simple-->
<StackPanel>
  <TextBlock>Hello</TextBlock>
  <TextBlock>World</TextBlock>
</StackPanel>

明示的な構文で UIElementCollection がコメント アウトされている点に注目してください。コメント アウトされている理由は、対象のコレクションがオブジェクト ツリーに存在する場合でも XAML で明示的に指定することはできないからです。それは、UIElementCollection が構築可能なクラスではないからです。ランタイム オブジェクト ツリーで取得する値は、初期化後に変更することができない、所有するクラスからの既定の初期化値です。状況によっては、あえて明示的にコレクション クラスをマークアップに含めることもあります (コレクションに x:Name を付けて、コード内で参照しやすくするなど)。ただし、バッキング型の特性上、または読み取り専用のコレクション プロパティが設定されているために、XAML パーサーによる構築ができないコレクション クラスを明示的に宣言することのないように十分注意してください。

プロパティの設定で属性構文またはプロパティ要素構文を使用する状況

XAML で設定可能なプロパティはいずれも、直接値を設定するための属性構文またはプロパティ要素構文をサポートしますが、両方の構文をサポートしない可能性もあります。両方の構文をサポートするプロパティや、上記の Text に対するコンテンツ要素構文など他の構文オプションをサポートしているプロパティもあります。部分的にプロパティでサポートされる XAML 構文の種類は、そのプロパティでプロパティの型として使用されるオブジェクトの型によって決まります。プロパティ型がプリミティブ型 (倍精度浮動小数点、整数、文字列など) である場合、そのプロパティは常に属性構文をサポートします。

次の例では、属性構文を使用して Rectangle の幅を設定しています。Width プロパティは属性構文をサポートします。これは、プロパティ値が倍精度浮動小数点であるためです。

<Rectangle Width="100" />

プロパティを設定する際、その設定に使用するオブジェクト型を文字列の型変換によって作成できる場合は、属性構文を使用することもできます。これは、プリミティブについては必ず該当します。ただし、その他のオブジェクト型の中には、オブジェクト要素構文を使用するのではなく、属性値として指定された文字列を使用するだけで作成できるものもあります。この手法では、基になる型変換が使用されます。この型変換は、特定のプロパティでサポートされるか、通常は該当するプロパティ型でサポートされます。属性の文字列値が解析され、その文字列情報を使用して、新しいオブジェクトの初期化にとって重要なプロパティが設定されます。型コンバーターによっては、文字列の情報を処理する方法に応じて、一般的なプロパティ型のさまざまなサブクラスが作成される可能性もあります。この動作をサポートするオブジェクト型は、ドキュメントの構文のセクションに特別な文法が記載されます。

次の例では、属性構文を使用して Rectangle の塗りつぶしを設定しています。Fill プロパティは、SolidColorBrush を使用してこのプロパティを設定する場合に属性構文をサポートします。この理由は、Fill プロパティをサポートする Brush 抽象型が、型変換された文法をサポートするためです。この文法により、属性指定された文字列で Color として初期化される SolidColorBrush を作成できます (この具体例の詳細については、「Brush」および「SolidColorBrush」を参照してください)。

<Rectangle Width="100" Height="100" Fill="Blue" />

プロパティを設定する際、その設定に使用するオブジェクトがオブジェクト要素構文をサポートしている場合は、プロパティ要素構文を使用できます。対象のオブジェクトがオブジェクト要素構文をサポートしている場合は、プロパティもプロパティ要素属性をサポートします。次の例では、プロパティ要素構文を使用して Rectangle の塗りつぶしを設定しています。Fill プロパティでは、SolidColorBrush を使用してこのプロパティを設定する場合にプロパティ要素構文がサポートされます。これは、SolidColorBrush がオブジェクト要素構文をサポートしており、Brush 型を使って値を設定するというプロパティの要件を満たしているためです(SolidColorBrush には、属性構文により Color プロパティも設定されています。この XAML をレンダリングすると、属性構文を使用して Fill を設定した上記の XAML の例とまったく同じ結果になります)。

<Rectangle Width="100" Height="100">
  <Rectangle.Fill>
    <SolidColorBrush Color="Blue"/>
  </Rectangle.Fill>
</Rectangle>

Brush 型コンバーターのため、SolidColorBrushBrush になっている場合に限り、新しい Fill 値のプロパティ要素構文または属性構文を (リソース参照やバインディングなどのマークアップ拡張機能の使用に頼らずに) 選択できます。Fill の設定で使用できるその他の Brush 型については、その型の Brush を作成するために型コンバーターの動作を利用することはできません。そのため、ImageBrush などのブラシを使用して Fill を設定する場合は、Fill に対してプロパティ要素構文を使用し、ImageBrush をオブジェクト要素として宣言してプロパティ値を指定するか、次のセクションに記載されているようにマークアップ拡張を使用する必要があります。

<Rectangle Width="100" Height="100">
  <Rectangle.Fill>
    <ImageBrush ImageSource="forest.jpg"/>
  </Rectangle.Fill>
</Rectangle>

マークアップ拡張は、XAML 言語の概念であり、Windows Phone XAML 実装で顕著に使用されています。XAML 属性構文では、中かっこ ({}) によってマークアップ拡張機能の使用を示します。これにより、XAML プロセッサの通常の処理 (リテラル文字列か、直接文字列に変換できる値のいずれかとして属性値を扱う処理) がエスケープされます。代わりに、一般にパーサーでは、特定のマークアップ拡張をサポートするコードが呼び出されます。このコードは、マークアップからオブジェクト ツリーを作成する際に役立ちます。

Windows Phone は、既定の Windows Phone XAML 名前空間で定義され、XAML パーサーが認識できる次のマークアップ拡張機能をサポートしています。

  • Binding: データ コンテキストで解釈されるときまでプロパティ値を保留するデータ バインディングをサポートします。

  • StaticResource: ResourceDictionary で定義されているリソース値の参照をサポートします。

  • TemplateBinding: テンプレート オブジェクトのコード プロパティと対話できる XAML のコントロール テンプレートをサポートします。

  • RelativeSource: 特定の形式のテンプレート バインディングを有効にします。

Windows Phone では、XAML 言語の XAML 名前空間で定義される基本的なマークアップ拡張機能である x:Null もサポートしています。

コンバーターを持たない参照型の値を受け取るプロパティでは、プロパティ要素構文 (常に新しいインスタンスが作成されます) か、マークアップ拡張によるオブジェクト参照が必要になります。一般に、Windows Phone のマークアップ拡張機能では、既存のインスタンスがアプリのオブジェクト グラフの他の部分から返されるか、値が実行時まで保留されます。こうしたマークアップ拡張を使用すると、XAML で設定可能なすべてのプロパティが、属性構文で設定できるようになる可能性があります。属性構文でオブジェクトを直接インスタンス化できないプロパティでも、属性構文を使用して、プロパティの参照値を指定できます。また、XAML のプロパティを値の型または JIT 生成参照の型で指定するという通常の要件とは異なる動作を有効にすることもできます。

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

<Canvas.Resources>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="BorderBrush" Value="Blue"/>
    <Setter Property="BorderThickness" Value="5"/>
  </Style>
</Canvas.Resources>
...
<Border Style="{StaticResource PageBackground}">
  ...
</Border>

多くの場合、マークアップ拡張を使用することによって、既存のオブジェクトの参照である値を提供することも、プロパティを属性の形式で設定できるようにするオブジェクトを提供することもできます。

Windows Phone では、カスタム マークアップ拡張機能の定義を可能にする基本クラスを利用できます。

リテラルの "{" 値

左中かっこ記号 ({) はマークアップ拡張機能シーケンスの開始を表すため、{ で始まるリテラル文字列値を指定するには、エスケープ シーケンスを使用する必要があります。エスケープ シーケンスは {} です。たとえば、単一の左中かっこを表す文字列値を指定するには、属性値を {}{ として指定します。場合によっては、{ 値を文字列として指定するために、代替引用符 ("" で区切られた属性値内の ' など) を使用することもできます。

型コンバーターは、XAML から属性値を受け取り、この文字列値を使用して文字列ではない結果値を作成する概念上のエンティティです。型コンバーターは、オブジェクトのバッキング型や、ときには特定のプロパティに関連付けられます。型コンバーターにアクセスする場合、XAML マークアップからの特別な使用は必要ありません。XAML プロセッサは、XAML プロセッサが実行する一般的な型マッピング動作の一部としてバッキング型を読み取り、これらの型で型コンバーターがサポートされるかどうかを判定し、値の取得時に必要に応じてこの型コンバーターを起動します。

「プロパティの設定」で既に説明したように、型コンバーターは、通常であればプロパティ構文が必要になる場合に属性構文を有効にします。通常は、マークアップ形式を単純化するためにこの方法を使用します。いくつかの型コンバーターは、非常に単純な変換動作を提供します。たとえば、NullableBoolConverter では、Nullable<bool> 値の 3 つの状態を truefalse、および {x:Null} の文字列として指定できます。Windows Phone のリファレンス ドキュメントでは、型コンバーターによって有効化される XAML 構文は、通常はバッキング TypeConverter クラスに示されていません。代わりに、型コンバーターが有効な構文を使用できるそれぞれのオブジェクトまたはプロパティのリファレンス ページに、属性構文の詳細が示されています。通常は、Windows Phone で TypeConverter メソッドを直接呼び出す必要はありません。

十分に理解するのに構文または文法ガイドが必要なほど非常に複雑な "ミニ言語" をサポートする型コンバーターも、少数ですが存在します。

型コンバーターは、Windows Phone において主に XAML のサポート クラスとして存在し、カスタム型をサポートする型コンバーターを作成する際に基本クラスとして使用します。

XAML は、オブジェクトおよびそのプロパティを記述するための宣言型言語ですが、マークアップ内のオブジェクトにイベント ハンドラーをアタッチするための構文も備えています。XAML イベント構文規則は、プログラミング モデルを利用して XAML で宣言されたイベントを統合する Windows Phone などの特定のテクノロジで拡張できます。関連するイベントの名前は、そのイベントが処理されるオブジェクトの属性名として指定します。属性値には、コードで定義するイベント ハンドラー関数の名前を指定します。XAML プロセッサはこの名前を使用して、読み込まれたオブジェクト ツリーにデリゲート表現を作成し、指定されたハンドラーを内部ハンドラー リストに追加します。

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

ResourceDictionary の作成は、一般的な作業の 1 つです。通常は、すべてのリソース ディクショナリを XAML で記述することによって行います。ただし、リソース ディクショナリの概念とその使用方法については、このトピックでは解説しません。

XAML 言語は、基本的に XML 言語に基づいています。有効な XAML ファイルは、本質的に有効な XML ファイルです。ただし、XAML は XML と比較して大幅に拡張されています。特にバッキング型の概念に対する関係からスキーマの概念が大きく異なるほか、アタッチされたメンバーやマークアップ拡張機能などの言語要素が追加されています。xml:lang は XAML で有効ですが、解析動作の際ではなく実行時に作用し、一般的にフレームワーク レベルのプロパティに対するエイリアスが設定されます。詳細については、「FrameworkElement.Language」を参照してください。xml:base は、マークアップで有効ですが、Windows Phone XAML では無視されます。xml:space は有効ですが、「空白の処理」で説明するシナリオにのみ関連します。encoding 属性は XAML で有効です。UTF-8 および UTF-16 エンコーディングのみがサポートされます。UTF-32 はサポートされていません。

XAML での大文字と小文字の区別

XAML は、大文字と小文字を区別する言語です。XAML が XML を基にしているため、XML と同じく大文字と小文字が区別されます。XAML 要素および属性の名前では、大文字と小文字が区別されます。属性の値は、場合によって大文字と小文字が区別されます。これは、特定のプロパティに対して属性値がどのように処理されるかによって決まります。たとえば、属性値で列挙型のメンバー名が宣言されている場合、その列挙型メンバーの値を返すためにメンバー名文字列を型変換する組み込みの動作では、大文字と小文字は区別されません。一方、Name プロパティの値では、Name プロパティで宣言した名前に基づきオブジェクトを操作するユーティリティ メソッドと同様に、名前の文字列の大文字と小文字が区別されます。

XML と同様に、XAML の空白文字は、スペース、ラインフィード、およびタブです。これらは、それぞれ Unicode 値の 0020、000A、および 0009 に対応します。

既定では、XAML プロセッサで XAML ファイル内の要素間で検出された内部テキストを処理する場合、次に示す空白の標準化が行われます。

  • 東アジア言語の文字間のラインフィード文字は削除されます。"東アジア言語の文字" の定義については、後の「東アジア言語の文字」を参照してください。

  • すべての空白文字 (スペース、ラインフィード、タブ) は、スペースに変換されます。

  • 連続した複数のスペースはすべて削除され、1 つのスペースに置換されます。

  • 開始タグの直後にあるスペースは削除されます。

  • 終了タグの直前にあるスペースは削除されます。

"既定" とは、xml:space 属性の既定値で表される状態に対応します。

内部テキスト内の空白、および文字列プリミティブ

上記の標準化規則は、XAML 要素内で検出された内部テキストに適用されます。標準化の後、XAML プロセッサはすべての内部テキストを適切な型に次のように変換します。

  • プロパティの型がコレクションでなく、直接的に Object 型でない場合、XAML プロセッサはその型の型コンバーターを使用して、その型への変換を試行します。その際、変換に失敗すると、XAML パーサー エラーが発生します。

  • プロパティの型がコレクションで、内部テキストが連続している (間に要素タグがない) 場合、その内部テキストは単一の String として解析されます。そのコレクション型が String を受け入れない場合にも、XAML パーサー エラーが発生します。

  • プロパティの型が Object である場合、その内部テキストは単一の String として解析されます。その内部テキストの中に要素タグが含まれている場合には、XAML パーサー エラーが発生します。これは、Object 型は単一のオブジェクト (String など) を示しているためです。

  • プロパティの型がコレクションであり、内部テキストが連続していないことがあります。この場合、最初の部分文字列は String に変換されてコレクション項目として追加されます。中間にある要素はコレクション項目として追加され、この要素の後に続く部分文字列 (存在する場合) は 3 番目の String 項目としてコレクションに追加されます。

空白とテキスト コンテンツ モデル

実際には、空白の保持は、すべてのコンテンツ モデルのサブセットに関してのみ問題になります。このサブセットは、ある種のシングルトン String 型、専用の String コレクション、またはリスト、コレクション、またはディクショナリでの String と他の型の組み合わせをとることのできるコンテンツ モデルから構成されます。

文字列をとることのできるコンテンツ モデルの場合でも、これらのコンテンツ モデル内での既定の動作では、残っているすべての空白は、重要な空白としては扱われません。

通常、空白を重要な空白として扱うコントロールまたは他の型の詳細については、「Windows Phone のテキストとフォント」を参照してください。

空白の保持

ソース XAML で空白を保持し、XAML プロセッサによる空白の標準化の影響を受けずに最終的に表示されるようにするには、いくつかの手法があります。

xml:space="preserve": 空白を保持する必要がある要素のレベルでこの属性を指定します。この場合、たとえばマークアップ要素を配置する際に入れ子になっていることがひとめでわかるようにコード編集アプリによって追加されたスペースも含めて、すべての空白が保持されますが、これらのスペースが表示されるかどうかは、スペースを含んでいる要素のコンテンツ モデルの問題であることに注意する必要があります。オブジェクト モデルの大多数では、空白が何らかの意味で重要な空白と見なされることはないため、xml:space="preserve" をルート レベルで指定することはお勧めしません。この属性は、文字列内の空白を表示する要素のレベル、または空白が重要なコレクションである要素のレベルでのみ設定することをお勧めします。

エンティティおよび改行しないスペース: XAML では、テキスト オブジェクト モデル内に任意の Unicode エンティティを配置できます。改行しないスペース (UTF-8 エンコーディングでは &#160;) など、専用のエンティティを使用できます。改行しないスペース文字をサポートするリッチ テキスト コントロールも使用できます。インデントなどのレイアウト特性をシミュレートするためにエンティティを使用する場合には、パネルや余白の適切な使用など、エンティティの実行時出力が、一般的なレイアウト機能よりも多くの要因に基づいて変化するため、注意が必要です。

東アジア言語の文字

"東アジア言語の文字" は、U+20000 ~ U+2FFFD および U+30000 ~ U+3FFFD の範囲の Unicode 文字のセットとして定義されています。このサブセットは、"CJK 表意文字" と呼ばれることもあります。詳細については、http://www.unicode.org を参照してください。

表示:
© 2014 Microsoft