XAML ノード ストリームの構造と概念
.NET XAML サービスで実装される XAML リーダーと XAML ライターは、XAML ノード ストリームの設計概念に基づいています。 XAML ノード ストリームは、一連の XAML ノードの概念化です。 この概念化では、XAML プロセッサは、XAML 内のノード リレーションシップの構造を一度に 1 つずつ説明します。 開いている XAML ノード ストリームには、いつでも 1 つの現在のレコードまたは現在の位置のみが存在し、API の多くの側面では、その位置から利用可能な情報のみが報告されます。 XAML ノード ストリーム内の現在のノードは、オブジェクト、メンバー、または値として記述できます。 XAML を XAML ノード ストリームとして扱うことで、XAML リーダーは XAML ライターと通信し、XAML を含む読み込みパスまたは保存パス操作の間に、プログラムが XAML ノード ストリームの内容を表示、操作、または変更できるようにします。 XAML リーダーおよびライター API の設計と XAML ノード ストリームの概念は、XML ドキュメント オブジェクト モデル (DOM) や XmlReader クラスや XmlWriter クラスなど、以前の関連するリーダーおよびライターの設計と概念に似ています。 このトピックでは、XAML ノード ストリームの概念について説明し、XAML ノード レベルで XAML 表現と対話するルーチンを記述する方法について説明します。
XAML リーダーへの XAML の読み込み
基本 XamlReader クラスでは、最初の XAML を XAML リーダーに読み込むための特定の手法は宣言されていません。 代わりに、派生クラスは、XAML の入力ソースの一般的な特性と制約など、読み込み手法を宣言して実装します。 たとえば、XamlObjectReader は、ルートまたはベースを表す 1 つのオブジェクトの入力ソースから開始して、オブジェクト グラフを読み取ります。 その後、XamlObjectReader は、オブジェクト グラフから XAML ノード ストリームを生成します。
最も目立つ .NET XAML サービス定義 XamlReader サブクラスは XamlXmlReaderです。 XamlXmlReader ストリームまたはファイル パスを介してテキスト ファイルを直接読み込むか、関連するリーダー クラス (TextReaderなど) を介して間接的に、最初の XAML を読み込みます。 XamlReader は、読み込まれた後に XAML 入力ソース全体を含むものとして考えることができます。 ただし、XamlReader ベース API は、リーダーが XAML の単一ノードと対話するように設計されています。 最初に読み込まれた最初の単一ノードは、XAML のルートとその開始オブジェクトです。
XAML ノード ストリームの概念
XML ベースのテクノロジにアクセスするための DOM、ツリーメタファー、またはクエリベースのアプローチに慣れている場合、XAML ノード ストリームを概念化する便利な方法は次のとおりです。 読み込まれた XAML が DOM またはツリーであり、可能なすべてのノードがすべての方法で展開され、直線的に表示されるとします。 ノードを進めるにつれて、DOM に関連するレベルの "in" または "out" を走査している可能性がありますが、これらのレベルの概念はノード ストリームに関連しないため、XAML ノード ストリームは明示的に追跡されません。 ノード ストリームには "現在" の位置がありますが、ストリームの他の部分を参照として自分で保存していない限り、現在のノード位置以外のノード ストリームのすべての側面は表示されません。
XAML ノード ストリームの概念には、ノード ストリーム全体を通過する場合、XAML 表現全体を処理したと確信できるという顕著な利点があります。クエリ、DOM 操作、または情報を処理するためのその他の非線形アプローチが、完全な XAML 表現の一部を逃したことを心配する必要はありません。 このため、XAML ノード ストリーム表現は、XAML リーダーと XAML ライターを接続する場合と、XAML 処理操作の読み取りフェーズと書き込みフェーズの間で動作する独自のプロセスを挿入できるシステムを提供する場合の両方に最適です。 多くの場合、XAML ノード ストリーム内のノードの順序は、ソース テキスト、バイナリ、またはオブジェクト グラフでの順序と比較して、XAML リーダーによって意図的に最適化または並べ替えられます。 この動作は、XAML ライターがノード ストリーム内で "戻る" 必要がある位置に XAML ライターが存在しない XAML 処理アーキテクチャを適用することを目的としています。 理想的には、すべての XAML 書き込み操作は、スキーマ コンテキストとノード ストリームの現在位置に基づいて動作できる必要があります。
基本的な読み取りノード ループ
XAML ノード ストリームを調べるための基本的な読み取りノード ループは、次の概念で構成されます。 このトピックで説明するノード ループでは、XamlXmlReaderを使用して、人間が判読できるテキスト ベースの XAML ファイルを読み取っていることを前提としています。 このセクションのリンクは、XamlXmlReaderによって実装される特定の XAML ノード ループ API を参照します。
XAML ノード ストリームの末尾にないことを確認します (IsEof確認するか、Read 戻り値を使用します)。 ストリームの最後にいる場合は、現在のノードがないため、終了する必要があります。
NodeTypeを呼び出して、XAML ノード ストリームが現在公開しているノードの種類を確認します。
直接接続されている XAML オブジェクト ライターが関連付けられている場合は、通常、この時点で WriteNode を呼び出します。
現在のノードまたは現在のレコードとして報告される XamlNodeType に基づいて、次のいずれかを呼び出して、ノードの内容に関する情報を取得します。
StartMember または EndMemberの NodeType については、Member を呼び出して、メンバーに関する XamlMember 情報を取得します。 メンバーは XamlDirectiveである可能性があるため、必ずしも前のオブジェクトの従来の型定義メンバーであるとは限りません。 たとえば、オブジェクトに適用
x:Name
は、IsDirective が true で、メンバーの Name がName
されている XAML メンバーとして表示されます。その他のプロパティは、このディレクティブが XAML 言語 XAML 名前空間の下にあることを示します。StartObject または EndObjectの NodeType の場合は、Type を呼び出して、オブジェクトに関する XamlType 情報を取得します。
Valueの NodeType については、Valueを呼び出します。 ノードは、メンバーの値の最も単純な式、またはオブジェクトの初期化テキストである場合にのみ値です (ただし、このトピックの以降のセクションで説明するように、型変換の動作に注意する必要があります)。
NamespaceDeclarationの NodeType の場合は、Namespace を呼び出して名前空間ノードの名前空間情報を取得します。
Read 呼び出して XAML リーダーを XAML ノード ストリーム内の次のノードに進め、手順をもう一度繰り返します。
.NET XAML サービスの XAML リーダーによって提供される XAML ノード ストリームは、常にすべての可能なノードの完全な深いトラバーサルを提供します。 XAML ノード ループの一般的なフロー制御手法には、while (reader.Read())
内で本文を定義し、ノード ループ内の各ノード ポイントで NodeType をオンに切り替える方法があります。
ノード ストリームがファイルの末尾にある場合、現在のノードは null です。
リーダーとライターを使用する最も単純なループは、次の例のようになります。
XamlXmlReader xxr = new XamlXmlReader(new StringReader(xamlStringToLoad));
//where xamlStringToLoad is a string of well formed XAML
XamlObjectWriter xow = new XamlObjectWriter(xxr.SchemaContext);
while (xxr.Read()) {
xow.WriteNode(xxr);
}
この読み込みパスの XAML ノード ループの基本的な例では、XAML リーダーと XAML ライターが透過的に接続され、XamlServices.Parse使用した場合と何も変わることはありません。 しかし、この基本的な構造は、読み取りまたは書き込みのシナリオに適用されるように拡張されます。 考えられるシナリオは次のとおりです。
NodeTypeをオンにします。 読み取るノードの種類に応じて、さまざまなアクションを実行します。
すべてのケースで WriteNode を呼び出さないでください。 一部の NodeType ケースでは、WriteNode のみを呼び出します。
特定のノード タイプのロジック内で、そのノードの詳細を分析し、それらに対処します。 たとえば、特定の XAML 名前空間から取得したオブジェクトのみを書き込み、その XAML 名前空間からではなくオブジェクトを削除または延期できます。 または、メンバー処理の一部として XAML システムがサポートしていない XAML ディレクティブを削除または再処理することもできます。
Write*
メソッドをオーバーライドするカスタム XamlObjectWriter を定義します。場合によっては、XAML スキーマ コンテキストをバイパスする型マッピングを実行します。既定以外の XAML スキーマ コンテキストを使用する XamlXmlReader を構築し、XAML 動作のカスタマイズされた相違点がリーダーとライターの両方で使用されるようにします。
ノード ループの概念を超えた XAML へのアクセス
XAML ノード ループ以外の XAML 表現を操作する方法は他にもあります。 たとえば、インデックス付きノードを読み取ったり、特に x:Name
、x:Uid
、または他の識別子を介してノードに直接アクセスしたりできる XAML リーダーが存在する可能性があります。 .NET XAML サービスは完全な実装を提供しませんが、サービスとサポート型を通じて推奨されるパターンを提供します。 詳細については、「IXamlIndexingReader と XamlNodeList」を参照してください。
現在のノードの操作
XAML ノード ループを使用するほとんどのシナリオでは、ノードを読み取るだけではありません。 ほとんどのシナリオでは、現在のノードを処理し、各ノードを一度に 1 つずつ XamlWriterの実装に渡します。
一般的な読み込みパス のシナリオでは、XamlXmlReader は XAML ノード ストリームを生成します。XAML ノードは、ロジックと XAML スキーマ コンテキストに従って処理されます。ノードは XamlObjectWriterに渡されます。 その後、結果のオブジェクト グラフをアプリケーションまたはフレームワークに統合します。
一般的な保存パス のシナリオでは、XamlObjectReader がオブジェクト グラフを読み取り、個々の XAML ノードが処理され、XamlXmlWriter によってシリアル化された結果が XAML テキスト ファイルとして出力されます。 重要なのは、パスとシナリオの両方で一度に 1 つの XAML ノードを操作する必要があり、XAML ノードは、XAML 型システムと the.NET XAML サービス API によって定義された標準化された方法で処理できるということです。
フレームとスコープ
XAML ノード ループは、XAML ノード ストリームを直線的に進みます。 ノード ストリームは、オブジェクト、他のオブジェクトを含むメンバーなどに走査されます。 多くの場合、フレームとスタックの概念を実装することで、XAML ノード ストリーム内のスコープを追跡すると便利です。 これは、ノード ストリーム内でノード ストリームをアクティブに調整している場合に特に当てはまります。 ノード ループ ロジックの一部として実装するフレームとスタックのサポートでは、構造体が DOM の観点から考えられる場合、XAML ノード構造に降りると、StartObject
(または GetObject
) と EndObject
スコープがカウントされる可能性があります。
オブジェクト ノードの走査と入力
XAML リーダーによってノード ストリームが開かれる最初のノードは、ルート オブジェクトの開始オブジェクト ノードです。 定義上、このオブジェクトは常に 1 つのオブジェクト ノードであり、ピアはありません。 実際の XAML の例では、ルート オブジェクトは、より多くのオブジェクトを保持する 1 つ以上のプロパティを持つよう定義されており、これらのプロパティにはメンバー ノードがあります。 その後、メンバー ノードには 1 つ以上のオブジェクト ノードがあるか、値ノードで終了することもあります。 ルート オブジェクトは通常、XAML 名前スコープを定義します。XAML 名前スコープは XAML テキスト マークアップの属性として構文的に割り当てられますが、XAML ノード ストリーム表現の Namescope
ノード型にマップされます。
次の XAML の例を考えてみましょう (これは任意の XAML であり、.NET の既存の型ではサポートされていません)。 このオブジェクト モデルでは、FavorCollection
が Favor
、Balloon
、NoiseMaker
が Favor
に割り当てられる List<T>
であり、WPF が既知の色名として色を定義する方法と同様の Color
オブジェクトによって Balloon.Color
プロパティがサポートされ、属性構文の型コンバーターがサポート Color
と仮定します。
XAML マークアップ | 結果の XAML ノード ストリーム |
---|---|
<Party |
Party の Namespace ノード |
xmlns="PartyXamlNamespace"> |
Party の StartObject ノード |
<Party.Favors> |
Party.Favors の StartMember ノード |
暗黙的な FavorCollection の StartObject ノード |
|
暗黙的な FavorCollection items プロパティのノードを StartMember します。 |
|
<Balloon |
Balloon の StartObject ノード |
Color="Red" |
Color の StartMember ノード属性値文字列 "Red" の Value ノードColor の EndMember |
HasHelium="True" |
HasHelium の StartMember ノード属性値文字列 "True" の Value ノードHasHelium の EndMember |
> |
Balloon の EndObject |
<NoiseMaker>Loudest</NoiseMaker> |
NoiseMaker の StartObject ノード_Initialization の StartMember ノード初期化値文字列 "Loudest" の Value ノード_Initialization の EndMember ノードNoiseMaker の EndObject |
暗黙的な FavorCollection items プロパティのノードを EndMember します。 |
|
暗黙的な FavorCollection の EndObject ノード |
|
</Party.Favors> |
Favors の EndMember |
</Party> |
Party の EndObject |
XAML ノード ストリームでは、次の動作に依存できます。
Namespace
ノードが存在する場合は、xmlns
で XAML 名前空間を宣言したStartObject
の直前にストリームに追加されます。 XAML とノード ストリームの例を含む前のテーブルをもう一度見てください。StartObject
ノードとNamespace
ノードが、テキスト マークアップ内での宣言位置と置き換えられるように見えることに注目してください。 これは、名前空間ノードがノード ストリーム内で適用されるノードの前に常に表示される動作を表します。 この設計の目的は、名前空間情報がオブジェクト ライターにとって不可欠であり、オブジェクト ライターが型マッピングの実行またはオブジェクトの処理を試みる前に知る必要があるということです。 XAML 名前空間情報をストリーム内のアプリケーション スコープの前に配置すると、ノード ストリームを常に表示された順序で処理するのが簡単になります。上記の考慮事項により、ルートの
Namespace
StartObject
ではなく、ノードを最初に読み取るノードは、ほとんどの実際のマークアップ ケースで最初に読み取ります。StartObject
ノードの後には、StartMember
、Value
、または即時EndObject
を指定できます。 それはすぐに別のStartObject
が続くことはありません.StartMember
の後には、StartObject
、Value
、または即時EndMember
を指定できます。 新しい値をインスタンス化するStartObject
ではなく、親オブジェクトの既存の値から値が取得されるメンバーの場合は、GetObject
を続けることができます。 また、次のStartObject
に適用されるNamespace
ノードが続くこともできます。 それはすぐに別のStartMember
が続くことはありません.Value
ノードは値自体を表します。"EndValue" はありません。 これは、EndMember
によってのみ続くことができます.構築で使用される可能性があるオブジェクトの XAML 初期化テキストは、Object-Value 構造体になりません。 代わりに、
_Initialization
という名前のメンバーの専用メンバー ノードが作成されます。 そのメンバー ノードには初期化値文字列が含まれています。 存在する場合、_Initialization
は常に最初のStartMember
です。_Initialization
は、一部の XAML サービス表現で XAML 言語の XAML 名前スコープを使用して修飾できます。そのため、_Initialization
はバッキング型で定義されたプロパティではないことが明確になります。Member-Value の組み合わせは、値の属性設定を表します。 最終的には、この値の処理に関係する値コンバーターが存在する可能性があり、値はプレーン文字列です。 ただし、これは XAML オブジェクト ライターがこのノード ストリームを処理するまで評価されません。 XAML オブジェクト ライターには、必要な XAML スキーマ コンテキスト、型システム マッピング、および値変換に必要なその他のサポートがあります。
EndMember
ノードの後には、後続のメンバーのStartMember
ノード、またはメンバー所有者のEndObject
ノードを指定できます。EndObject
ノードの後には、EndMember
ノードを続けることができます。 オブジェクトがコレクションの項目内のピアである場合は、StartObject
ノードの後に続くこともできます。 または、次のStartObject
に適用されるNamespace
ノードが続く場合もあります。- ノード ストリーム全体を閉じる一意のケースでは、ルートの
EndObject
の後に何も続かない。リーダーはファイルの終わりになり、Read はfalse
を返します。
- ノード ストリーム全体を閉じる一意のケースでは、ルートの
値コンバーターと XAML ノード ストリーム
値コンバーターは、マークアップ拡張機能、型コンバーター (値シリアライザーを含む)、または XAML 型システムを介して値コンバーターとして報告される別の専用クラスの一般的な用語です。 XAML ノード ストリームでは、型コンバーターの使用法とマークアップ拡張機能の使用法には、非常に異なる表現があります。
XAML ノード ストリームの型コンバーター
最終的に型コンバーターの使用が発生する属性セットは、XAML ノード ストリームでメンバーの値として報告されます。 XAML ノード ストリームは、型コンバーター インスタンス オブジェクトを生成して値を渡そうとしません。 型コンバーターの変換実装を使用するには、XAML スキーマ コンテキストを呼び出し、型マッピングに使用する必要があります。 値の処理に使用する必要がある型コンバーター クラスを決定する場合でも、XAML スキーマ コンテキストが間接的に必要です。 既定の XAML スキーマ コンテキストを使用する場合、その情報は XAML 型システムから入手できます。 XAML ライターに接続する前に XAML ノード ストリーム レベルで型コンバーター クラス情報が必要な場合は、設定されているメンバーの XamlMember 情報から取得できます。 ただし、それ以外の場合は、型マッピング システムと XAML スキーマ コンテキストを必要とする残りの操作 (XAML オブジェクト ライターによるオブジェクトの作成など) が実行されるまで、型コンバーターの入力を XAML ノード ストリームにプレーン値として保持する必要があります。
たとえば、次のクラス定義のアウトラインと XAML の使用方法を考えてみましょう。
public class BoardSizeConverter : TypeConverter {
//converts from string to an int[2] by splitting on an "x" char
}
public class GameBoard {
[TypeConverter(typeof(BoardSizeConverter))]
public int[] BoardSize; //2x2 array, initialization not shown
}
<GameBoard BoardSize="8x8"/>
この使用のための XAML ノード ストリームのテキスト表現は、次のように表されます。
GameBoard
を表す XamlType を使用した StartObject
BoardSize
を表す XamlMember を使用した StartMember
Value
ノード、テキスト文字列 "8x8
"
BoardSize
に一致する EndMember
GameBoard
に一致する EndObject
このノード ストリームに型コンバーター インスタンスがないことに注意してください。 しかし、BoardSize
の XamlMember で XamlMember.TypeConverter を呼び出すことで、型コンバーター情報を取得できます。 有効な XAML スキーマ コンテキストがある場合は、ConverterInstanceからインスタンスを取得してコンバーター メソッドを呼び出すこともできます。
XAML ノード ストリームのマークアップ拡張
マークアップ拡張機能の使用状況は、XAML ノード ストリームでメンバー内のオブジェクト ノードとして報告されます。この場合、オブジェクトはマークアップ拡張インスタンスを表します。 したがって、マークアップ拡張の使用法は、型コンバーターの使用法よりもノード ストリーム表現に明示的に示され、より多くの情報が含まれます。 XamlMember 使用は状況的であり、可能なマークアップケースごとに異なるため、マークアップ拡張について何も伝えられなかった。型コンバーターの場合と同様に、型またはメンバーごとに専用および暗黙的ではありません。
マークアップ拡張をオブジェクト ノードとしてノード ストリームで表現することは、マークアップ拡張機能の使用が XAML テキスト マークアップの属性形式で行われた場合でも当てはまります (多くの場合)。 明示的なオブジェクト要素フォームを使用したマークアップ拡張の使用法も同じように扱われます。
マークアップ拡張オブジェクト ノード内には、そのマークアップ拡張のメンバーが存在する可能性があります。 XAML ノード ストリーム表現では、位置指定パラメーターの使用法であるか、明示的な名前付きパラメーターを使用した使用法であるかに関係なく、そのマークアップ拡張機能の使用法が保持されます。
位置指定パラメーターを使用する場合、XAML ノード ストリームには、使用状況を記録する XAML 言語定義プロパティ _PositionalParameters
が含まれます。 このプロパティは、Object 制約を持つ汎用 List<T> です。 位置指定パラメーターを使用すると、その中に入れ子になったマークアップ拡張の使用法が含まれる可能性があるため、制約はオブジェクトであり、文字列ではありません。 使用法から位置パラメーターにアクセスするには、リストを反復処理し、個々のリスト値にインデクサーを使用できます。
名前付きパラメーターを使用する場合、各名前付きパラメーターは、ノード ストリーム内でその名前のメンバー ノードとして表されます。 入れ子になったマークアップ拡張が使用される可能性があるため、メンバー値は必ずしも文字列ではありません。
マークアップ拡張機能からの ProvideValue
はまだ呼び出されていません。 ただし、XAML リーダーと XAML ライターを接続すると呼び出され、ノード ストリームでマークアップ拡張ノードで WriteEndObject
が呼び出されます。 このため、一般に、読み込みパスでオブジェクト グラフを形成するために使用されるのと同じ XAML スキーマ コンテキストが必要です。 それ以外の場合、マークアップ拡張機能からの ProvideValue
は、予期されるサービスを使用できないため、ここで例外をスローできます。
XAML ノード ストリームの XAML および XML Language-Defined メンバー
特定のメンバーは、明示的な XamlMember 検索や構築ではなく、XAML リーダーの解釈と規則のために XAML ノード ストリームに導入されます。 多くの場合、これらのメンバーは XAML ディレクティブです。 場合によっては、XAML ノード ストリームにディレクティブを導入する XAML を読み取る動作です。 つまり、元の入力 XAML テキストはメンバー ディレクティブを明示的に指定しませんでしたが、XAML リーダーは、構造 XAML 規則を満たすためにディレクティブを挿入し、その情報が失われる前に XAML ノード ストリームに情報を報告します。
次の一覧は、XAML リーダーがディレクティブ XAML メンバー ノードを導入することが予想されるすべてのケースと、そのメンバー ノードが .NET XAML Services 実装でどのように識別されるかを示しています。
オブジェクト ノードの初期化テキスト: このメンバー ノードの名前は
_Initialization
。XAML ディレクティブを表し、XAML 言語の XAML 名前空間で定義されます。 Initializationから静的エンティティを取得できます。マークアップ拡張機能の位置指定パラメーター: このメンバー ノードの名前が
_PositionalParameters
され、XAML 言語の XAML 名前空間で定義されます。 常にオブジェクトの汎用リストが含まれています。各オブジェクトは、入力 XAML で指定された,
区切り文字で分割することによって事前に区切られた位置パラメーターです。 PositionalParametersから位置指定パラメーター ディレクティブの静的エンティティを取得できます。不明なコンテンツ: このメンバー ノードの名前が
_UnknownContent
。 厳密に言えば、これは XamlDirectiveであり、XAML 言語の XAML 名前空間で定義されています。 このディレクティブは、XAML オブジェクト要素にソース XAML のコンテンツが含まれているが、現在使用可能な XAML スキーマ コンテキストではコンテンツ プロパティを特定できない場合に、センチネルとして使用されます。 XAML ノード ストリームでこのケースを検出する場合は、_UnknownContent
という名前のメンバーを確認します。 読み込みパス XAML ノード ストリームで他のアクションが実行されない場合、既定の XamlObjectWriter は、任意のオブジェクトで_UnknownContent
メンバーを検出したときに、試行されたWriteEndObject
でスローされます。 既定の XamlXmlWriter はスローされず、メンバーを暗黙的として扱います。 UnknownContentから_UnknownContent
の静的エンティティを取得できます。コレクションのコレクション プロパティ: XAML に使用されるコレクション クラスのバッキング CLR 型には、通常、コレクション項目を保持する専用の名前付きプロパティがありますが、そのプロパティは、バッキング型解決の前に XAML 型システムでは認識されません。 代わりに、XAML ノード ストリームには、コレクション XAML 型のメンバーとして
Items
プレースホルダーが導入されています。 .NET XAML サービスの実装では、ノード ストリーム内のこのディレクティブまたはメンバーの名前が_Items
。 このディレクティブの定数は、Itemsから取得できます。XAML ノード ストリームには、バッキング型の解決と XAML スキーマ コンテキストに基づいて解析できないアイテムを含む Items プロパティが含まれている場合があることに注意してください。 例えば
XML で定義されたメンバー: XML 定義の
xml:base
、xml:lang
、およびxml:space
メンバーは、.NET XAML Services の実装でbase
、lang
、およびspace
という名前の XAML ディレクティブとして報告されます。 これらの名前空間は、XML 名前空間http://www.w3.org/XML/1998/namespace
です。 これらの各定数は、XamlLanguageから取得できます。
ノードの順序
場合によっては、XamlXmlReader は、XAML ノード ストリーム内の XAML ノードの順序と、マークアップで表示された場合や XML として処理された場合にノードが表示される順序を変更します。 これは、XamlObjectWriter が順方向専用の方法でノード ストリームを処理できるようにノードを並べ替えるために行われます。 .NET XAML サービスでは、XAML リーダーは、ノード ストリームの XAML オブジェクト ライター コンシューマーのパフォーマンス最適化として、このタスクを XAML ライターに任せずにノードの順序を変更します。
特定のディレクティブは、オブジェクト要素からオブジェクトを作成するための詳細情報を提供することを目的としています。 これらのディレクティブは、Initialization
、PositionalParameters
、TypeArguments
、FactoryMethod
、Arguments
です。 .NET XAML サービス XAML リーダーは、次のセクションで説明する理由から、オブジェクトの StartObject
に続くノード ストリームの最初のメンバーとしてこれらのディレクティブを配置しようとします。
XamlObjectWriter の動作とノードの順序
XamlObjectWriter への StartObject
は、必ずしも、オブジェクト インスタンスをすぐに構築するための XAML オブジェクト ライターへのシグナルであるとは限りません。 XAML には、追加の入力を使用してオブジェクトを初期化し、パラメーターなしのコンストラクターを呼び出して初期オブジェクトを生成し、プロパティを設定することに完全に依存しないようにするための、いくつかの言語機能が含まれています。 次の機能が含まれます: XamlDeferLoadAttribute;初期化テキスト。x:TypeArguments;マークアップ拡張の位置指定パラメーター。ファクトリ メソッドと関連付けられた x:Arguments ノード (XAML 2009)。 これらの各ケースでは、実際のオブジェクトの構築が遅れ、ノード ストリームの順序が変更されるため、XAML オブジェクト ライターは、そのオブジェクト型の構築ディレクティブではない開始メンバーが検出されるたびに、インスタンスを実際に構築する動作に依存できます。
GetObject
GetObject
は、新しいオブジェクトを構築するのではなく、XAML オブジェクト ライターがオブジェクトの包含プロパティの値を取得する必要がある XAML ノードを表します。 XAML ノード ストリームで GetObject
ノードが検出される一般的なケースは、コレクション オブジェクトまたはディクショナリ オブジェクトに対するものです。これは、包含プロパティがバッキング型のオブジェクト モデルで意図的に読み取り専用である場合です。 このシナリオでは、多くの場合、コレクションまたはディクショナリは、所有する型の初期化ロジックによって作成および初期化されます (通常は空)。
関連項目
- XamlObjectReader
- XAML サービス の
- XAML 名前空間 を
する
.NET Desktop feedback