XAML のマークアップ拡張機能の概要Markup Extensions for XAML Overview

マークアップ拡張機能は、プリミティブでも特定の XAML 型でもない値を取得するための XAML の手法です。Markup extensions are a XAML technique for obtaining a value that is neither a primitive nor a specific XAML type. 属性による使用では、マークアップ拡張機能は、左中かっこ { でマークアップ拡張機能スコープに入り、右中かっこ } で終了するという、既知の文字シーケンスを使用します。For attribute usage, markup extensions use the known character sequence of an opening curly brace { to enter the markup extension scope, and a closing curly brace } to exit. .NET Framework XAML サービスを使用する場合は、System.Xaml アセンブリから XAML 言語の定義済みのマークアップ拡張機能をいくつか使用できます。When using .NET Framework XAML Services, you can use some of the predefined XAML language markup extensions from the System.Xaml assembly. また、System.Xaml で定義された MarkupExtension クラスからサブクラスを作成し、独自のマークアップ拡張機能を定義することもできます。You can also subclass from the MarkupExtension class, defined in System.Xaml, and define your own markup extensions. あるいは、特定のフレームワークを既に参照している場合は、そのフレームワークによって定義されたマークアップ拡張機能を使用することができます。Or you can use markup extensions defined by a particular framework if you are already referencing that framework .

マークアップ拡張機能の使用にアクセスした XAML オブジェクト ライターは、 MarkupExtension オーバーライドのサービス接続ポイントを通じて、カスタム MarkupExtension.ProvideValue クラスにサービスを提供することができます。When a markup extension usage is accessed, the XAML object writer can provide services to a custom MarkupExtension class through a service connection point in the MarkupExtension.ProvideValue override. このサービスを使用すると、使用に関するコンテキスト、オブジェクト ライターの特定の機能、XAML スキーマ コンテキストなどを取得することができます。The services can be used to obtain context about the usage, specific capabilities of the object writer, XAML schema context, and so on.

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

XAML 言語をサポートするため、.NET Framework XAML サービスによっていくつかのマークアップ拡張機能が実装されています。Several markup extensions are implemented by .NET Framework XAML Services for XAML language support. これらのマークアップ拡張機能は、言語としての XAML の仕様の部分に対応しています。These markup extensions correspond to parts of the specification of XAML as a language. これらは、通常、一般的に使用される構文では x: プレフィックスによって識別できます。These are typically identifiable by the x: prefix in the syntax as seen in common usage. これらの XAML 言語要素に対する .NET Framework XAML サービスの実装は、すべて MarkupExtension 基底クラスから派生します。The .NET Framework XAML Services implementations for these XAML language elements all derive from the MarkupExtension base class .

注意

x: プレフィックスは、XAML 稼働環境のルート要素で、XAML 言語の名前空間を標準的な XAML 名前空間にマッピングするために使用します。The x: prefix is used for the typical XAML namespace mapping of the XAML language namespace, in the root element of a XAML production. たとえば、さまざまな特定のフレームワークの Visual Studio プロジェクトとページテンプレートでは、このx:マッピングを使用して XAML ファイルが開始されます。For example, the Visual Studio project and page templates for various specific frameworks initiate a XAML file using this x: mapping. 独自の XAML 名前空間のマッピングに別のプレフィックス トークンを選択することもできますが、このドキュメントでは、既定の x: マッピングを、独自の固有なフレームワークの既定の XAML 名前空間や他の任意の CLR 名前空間または XML 名前空間ではなく、XAML 言語の XAML 名前空間の一部として定義されているエンティティを識別する手段と想定します。You could choose a different prefix token in your own XAML namespace mapping, but this documentation will assume the default x: mapping as a means of identifying those entities that are a defined part of the XAML language XAML namespace, as opposed to a specific framework's default XAML namespace or other arbitrary CLR or XML namespaces.

x:Typex:Type

x:Type は、名前を指定した型の Type オブジェクトを提供します。x:Type supplies the Type object for the named type. この機能は、基になる CLR 型やそれから派生した型をグループ化のモニカーまたは識別子として使用する遅延メカニズムの中で最も頻繁に使用されます。This functionality is used most frequently in deferral mechanisms that use underlying CLR type and type derivation as a grouping moniker or identifier. 具体的な例には、WPF のスタイルとテンプレート、およびそれらにおける TargetType プロパティの使用があります。WPF styles and templates, and their usage of TargetType properties, are a specific example. 詳細については、「 x:Type Markup Extension」を参照してください。For more information, see x:Type Markup Extension.

x:Staticx:Static

x:Static は、直接的にはプロパティの値の型ではなくても、その型に評価することができる値型コード エンティティから、静的な値を生成します。x:Static produces static values from value-type code entities that are not directly the type of a property's value, but can be evaluated to that type. これは、型定義で既知の定数として既に存在する値を指定するときに便利です。This is useful for specifying values that already exist as well-known constants in a type definition. 詳細については、「 x:Static Markup Extension」を参照してください。For more information, see x:Static Markup Extension.

x:Nullx:Null

x:Null は、XAML メンバーに対する値として null を指定します。x:Null specifies null as a value for a XAML member. 特定の型の設計やフレームワークの広義の概念によっては、 null がプロパティの既定値に該当しない場合や、空の文字列属性の暗黙的な値に該当しない場合もあります。Depending on the design of specific types or on larger framework concepts, null is not always a default value for a property, or the implied value of an empty string attribute. 詳細については、「 x:Null Markup Extension」を参照してください。For more information, see x:Null Markup Extension.

x:Arrayx:Array

x:Array は、XAML 構文での一般的な配列の作成をサポートします。基本要素とコントロール モデルで提供されているコレクションのサポートをあえて使用しない場合に使用します。x:Array supports creation of general arrays in XAML syntax in cases where the collection support that is provided by base elements and control models is deliberately not used. 詳細については、「 x:Array Markup Extension」を参照してください。For more information, see x:Array Markup Extension. XAML 2009 では、厳密に言うと、拡張機能としてではなく言語プリミティブとして配列にアクセスします。In XAML 2009 specifically, arrays are accessed as language primitives instead of as an extension. 詳細については、「 XAML 2009 Language Features」を参照してください。For more information, see XAML 2009 Language Features.

x:Referencex:Reference

x:Reference は XAML 2009 に含まれており、元 (2006) の言語セットの拡張機能です。x:Reference is part of XAML 2009, an extension of the original (2006) language set. x:Reference は、オブジェクト グラフにある別の既存のオブジェクトへの参照を表します。x:Reference represents a reference to another existing object in an object graph. このオブジェクトは、その x:Nameによって識別されます。That object is identified by its x:Name. 詳細については、「 x:Reference Markup Extension」を参照してください。For more information, see x:Reference Markup Extension.

その他の x:作成Other x: Constructs

XAML 言語機能をサポートするための他の x: コンストラクトも存在しますが、マークアップ拡張機能としては実装されていません。Other x: constructs to support XAML language features exist, but these are not implemented as markup extensions. 詳細については、「XAML 名前空間 (x:)」を参照してください。言語機能For more information, see XAML Namespace (x:) Language Features.

MarkupExtension 基底クラスThe MarkupExtension Base Class

System.Xaml の XAML リーダーと XAML ライターの既定の実装と対話できるカスタム マークアップ拡張機能を定義するには、抽象クラス MarkupExtension からクラスを派生します。To define a custom markup extension that can interact with the default implementations of XAML readers and XAML writers in System.Xaml, you derive a class from the abstract MarkupExtension class. このクラスには、オーバーライドする 1 つのメソッドとして、 ProvideValueがあります。That class has one method to override, which is ProvideValue. また、マークアップ拡張機能で使用する引数をサポートする追加のコンストラクターと、それに対応する設定可能なプロパティも定義する必要があります。You might also need to define additional constructors to support arguments to the markup extension usage, and matching settable properties.

カスタム マークアップ拡張機能は、 ProvideValueを通じて、マークアップ拡張機能が XAML プロセッサによって実際に起動された環境を報告するサービス コンテキストにアクセスします。Through ProvideValue, a custom markup extension has access to a service context that reports the environment where the markup extension is actually invoked by a XAML processor. 読み込みパスでは、これは通常 XamlObjectWriterです。In the load path this is typically a XamlObjectWriter. 保存パスでは、これは通常 XamlXmlWriterです。In the save path this is typically a XamlXmlWriter. これらはそれぞれ、サービス プロバイダー パターンを実装する内部 XAML サービス プロバイダー コンテキスト クラスとして、サービス コンテキストを報告します。Each report the service context as an internal XAML service provider context class that implements a service provider pattern. 使用できるサービスと、これらのサービスが何を表現するかについての詳細については、「 Type Converters and Markup Extensions for XAML」を参照してください。For more information about the available services and what they represent, see Type Converters and Markup Extensions for XAML.

マークアップ拡張機能クラスは、パブリックなアクセス レベルを使用する必要があります。XAML プロセッサは、マークアップ拡張機能のサービスを使用するために、そのマークアップ拡張機能のサポート クラスをいつでもインスタンス化できる必要があるからです。Your markup extension class must use a public access level; XAML processors must always be able to instantiate the markup extension's support class in order to use its services.

カスタム マークアップ拡張機能のサポート型の定義Defining the Support Type for a Custom Markup Extension

.NET Framework XAML サービス、または .NET Framework XAML サービスに基づいて構築されたフレームワークを使用する場合は、2 種類の方法でマークアップ拡張機能のサポート型に名前を付けることができます。When you use .NET Framework XAML Services or frameworks that build on .NET Framework XAML Services, you have two choices for how to name the markup extension support type. 型名は、XAML オブジェクト ライターが XAML 内でマークアップ拡張機能の使用を検出したときに、マークアップ拡張機能のサポート型にアクセスして呼び出しを試みる方法に関連しています。The type name is relevant to how XAML object writers attempt to access and invoke a markup extension support type when they encounter a markup extension usage in XAML. 次のいずれかの方法で名前を付けます。Use one of the following naming strategies:

  • XAML マークアップの使用トークンと完全に一致する型名を付ける。Name the type name to be an exact match to the XAML markup usage token. たとえば、 {Collate ...} 拡張機能の使用をサポートするためには、サポート型に Collateという名前を付けます。For example, to support a {Collate ...} extension usage, name the support type Collate.

  • 使用トークンの文字列に Extensionサフィックスを付加した型名を付ける。Name the type name to be the usage string token plus the suffix Extension. たとえば、 {Collate ...} 拡張機能の使用をサポートするためには、サポート型に CollateExtensionという名前を付けます。For example, to support a {Collate ...} extension usage, name the support type CollateExtension.

検索は、まずサフィックス Extensionが付加されたクラス名、次にサフィックス Extension が付加されていないクラス名という順序で行われます。The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix.

マークアップを使用する観点からは、サフィックス Extension を使用名の一部に含めることは有効です。From the markup usage perspective, including the Extension suffix as part of the usage is valid. ただし、この場合、 Extension は完全にクラス名の一部として扱われます。したがって、サポート クラスにサフィックス Extension が付いていない場合、XAML オブジェクト ライターはその使用についてマークアップ拡張機能のサポート クラスを解決できません。However, this behaves as if Extension is truly part of the class name, and XAML object writers would fail to resolve a markup extension support class for that usage if the support class did not have the Extension suffix.

既定のコンストラクターThe Default Constructor

すべてのマークアップ拡張機能のサポート型について、パブリックなパラメーターなしのコンストラクターを公開する必要があります。For all markup extension support types, you should expose a public parameterless constructor. XAML オブジェクトライターがオブジェクト要素の使用からマークアップ拡張機能をインスタンス化する場合は、パラメーターなしのコンストラクターが必要です。A parameterless constructor is required for any case where a XAML object writer instantiates the markup extension from an object element usage. マークアップ拡張機能でオブジェクト要素の使用がサポートされることは、特にシリアル化の場合には、正当な予想です。Supporting object element usage is a fair expectation for a markup extension, particularly for serialization. ただし、マークアップ拡張機能の属性による使用だけをサポートする場合は、パブリック コンストラクターなしでマークアップ拡張機能を実装することができます。However, you can implement a markup extension without a public constructor if you only intend to support attribute usages of the markup extension.

マークアップ拡張機能の使用に引数がない場合は、使用をサポートするためにパラメーターなしのコンストラクターが必要です。If your markup extension usage has no arguments, the parameterless constructor is required to support usage.

カスタム マークアップ拡張機能のコンストラクター パターンと位置指定引数Constructor Patterns and Positional Arguments for a Custom Markup Extension

引数の意図された使用方法のあるマークアップ拡張機能については、パブリック コンストラクターは、意図された使用方法のモードに対応する必要があります。For a markup extension with intended argument usage, the public constructors must correspond to the modes of the intended usage. つまり、有効な使用方法として位置指定引数を 1 つ使用するようにマークアップ拡張機能が設計されている場合であれば、その位置指定引数を取る 1 つの入力パラメーターを使用するパブリック コンストラクターをサポートする必要があります。In other words, if your markup extension is designed to require one positional argument as a valid usage, you should support a public constructor with one input parameter that takes the positional argument.

たとえば、 Collate マークアップ拡張機能が、モードを表す位置指定引数 ( CollationMode 列挙定数として指定される) が 1 つのモードのみをサポートするとします。For example, suppose the Collate markup extension is intended to support only a mode where there is one positional argument that represents its mode, specified as a CollationMode enumeration constant. この場合は、次の形式のコンストラクターが必要になります。In this case, there should be a constructor with the following form:

public Collate(CollationMode collationMode) {...}  

基本的なレベルでは、マークアップ拡張機能に渡される引数は、マークアップの属性値から転送されるので、文字列です。At a basic level, the arguments passed to a markup extension are a string because they are being forwarded from the markup's attribute values. すべての引数を文字列にし、入力をそのレベルで処理することができます。You can make all of your arguments strings and work with input at that level. ただし、マークアップ拡張機能の引数がサポート クラスに渡される前に実行される特定の処理にアクセスすることもできます。However, you do have access to certain processing that occurs before the markup extension arguments are passed to the support class.

この処理では、概念としては、マークアップ拡張機能を「作成するオブジェクト」と見なして、そのメンバー値を設定します。The processing works conceptually as if the markup extension is an object to be created, and then its member values are set. 設定するように指定された各プロパティは、作成するオブジェクトに指定されたメンバーが設定される場合と同じように、XAML が解析される時点で評価されます。Each specified property to set is evaluated similar to how a specified member can be set on a created object when XAML is parsed. 次の 2 つの重要な違いがあります。There are two important differences:

  • 前述のように、マークアップ拡張機能のサポート型では、XAML でインスタンス化するために、パラメーターなしのコンストラクターを持つ必要はありません。As noted previously, a markup extension support type does not need to have a parameterless constructor in order to be instantiated in XAML. オブジェクトの構築は、テキスト構文で使用できる引数が位置指定引数または名前付き引数のいずれかとしてトークン化および評価されるまで遅延され、その時点で適切なコンストラクターが呼び出されます。Its object construction is deferred until its possible arguments in the text syntax are tokenized and evaluated as either positional or named arguments, and the appropriate constructor is called at that time.

  • マークアップ拡張機能の使用は入れ子にすることができます。Markup extensions usages can be nested. 最も内側のマークアップ拡張機能が最初に評価されます。The innermost markup extension is evaluated first. そのため、そのような使用を想定して、いずれかの構築パラメーターを、生成するために値コンバーター (マークアップ拡張機能など) を必要とする型として宣言できます。Therefore, you can assume such a usage and declare one of the construction parameters to be a type that requires a value converter (such as a markup extension) to produce.

このような処理への依存については、前の例で説明したとおりです。A reliance on such processing was shown in the previous example. .NET Framework XAML サービスの XAML オブジェクト ライターは、列挙定数の名前を、ネイティブ レベルでの列挙値に処理します。The .NET Framework XAML Services XAML object writer processes enumeration constant names into enumerated values at a native level.

また、マークアップ拡張機能の位置指定パラメーターのテキスト構文を処理する際にも、構築引数にある型に関連付けた型コンバーターに依存するようにできます。Processing text syntax of a markup extension positional parameter can also rely on a type converter that is associated with the type that is in the construction argument.

引数が位置指定引数と呼ばれるのは、使用の中でトークンに出会う順序が、割り当てられたコンストラクター パラメーターの位置的な順序に対応するからです。The arguments are called positional arguments because the order in which the tokens in the usage is encountered corresponds to the positional order of the constructor parameter to which they are assigned. たとえば、次のようなコンストラクター シグネチャについて考えてみます。For example, consider the following constructor signature:

public Collate(CollationMode collationMode, object collateThis) {...}  

XAML プロセッサは、このマークアップ拡張機能に対して、2 つの位置指定引数を予期します。A XAML processor expects two positional arguments for this markup extension. {Collate AlphaUp,{x:Reference circularFile}}という使用があった場合、 AlphaUp トークンが最初のパラメーターに送られ、 CollationMode 列挙体の名前付き定数として評価されます。If there was a usage {Collate AlphaUp,{x:Reference circularFile}}, the AlphaUp token is sent to the first parameter and evaluated as a CollationMode enumeration named constant. 内側の x:Reference の結果は 2 つ目のパラメーターに送られ、オブジェクトとして評価されます。The result of the inner x:Reference is sent to the second parameter and evaluated as an object.

XAML で規定されているマークアップ拡張構文と処理の規則では、引数が位置指定引数の場合でも名前付き引数の場合でも、引数の区切り記号としてコンマが使用されます。In the XAML specified rules for markup extension syntax and processing, the comma is the delimiter between arguments, whether those arguments are positional arguments or named arguments.

位置指定引数の重複するアリティDuplicate Arity of Positional Arguments

XAML オブジェクト ライターが位置指定引数によるマークアップ拡張機能の使用を検出したときに、同じ数の引数 (重複するアリティ) を受け取る複数のコンストラクターが存在している場合でも、必ずしもエラーには該当しません。If a XAML object writer encounters a markup extension usage with positional arguments, and there are multiple constructor arguments that take that number of arguments (a duplicate arity), that is not necessarily an error. 実際の動作は、カスタマイズ可能な XAML スキーマ コンテキスト設定である SupportMarkupExtensionsWithDuplicateArityによって異なります。The behavior depends on a customizable XAML schema context setting, SupportMarkupExtensionsWithDuplicateArity. SupportMarkupExtensionsWithDuplicateAritytrueである場合は、重複するアリティのみを理由に、XAML オブジェクト ライターから例外がスローされることはありません。If SupportMarkupExtensionsWithDuplicateArity is true, a XAML object writer should not throw an exception only for reasons of duplicate arity. それ以上の動作は、厳密には定義されていません。Behavior beyond that point is not strictly defined. 基本的な設計では、スキーマ コンテキストには特定のパラメーターに対応する型情報が設定されており、明示的なキャストを試みて、重複する候補から最もよく一致するシグネチャを確認できる、ということを前提としています。The basic design assumption is that the schema context has type information available for the specific parameters and can attempt explicit casts that match the duplicate candidates to see which signature might be the best match. それでも、XAML オブジェクト ライターで実行されている特定のスキーマ コンテキストによってテストが行われ、そのテストに合格するシグネチャが存在しない場合に、例外がスローされる可能性があります。An exception might still be thrown if no signatures can pass the tests that are imposed by that particular schema context that is running on a XAML object writer.

既定では、 SupportMarkupExtensionsWithDuplicateArity は .NET Framework XAML サービスの CLR ベースの falseXamlSchemaContext になります。By default, SupportMarkupExtensionsWithDuplicateArity is false in the CLR-based XamlSchemaContext for .NET Framework XAML Services. したがって、バッキング型のコンストラクターに重複するアリティが存在している状況で、マークアップ拡張機能の使用を検出した場合に、既定の XamlObjectWriter が例外をスローします。Thus, the default XamlObjectWriter throws exceptions if it encounters a markup extension usage where there is duplicate arity in the backing type's constructors.

カスタム マークアップ拡張機能の名前付き引数Named Arguments for a Custom Markup Extension

XAML によって指定されるマークアップ拡張機能は、使用の際に名前付き引数の形式を使用することもできます。Markup extensions as specified by XAML can also use a named arguments form for usage. トークン化の最初のレベルでは、テキスト構文は引数に分割されます。At the first level of tokenization, the text syntax is divided into arguments. 引数内に等号 (=) が存在すると、引数は名前付き引数として識別されます。The presence of an equals sign (=) within any argument identifies an argument as a named argument. このような引数は、名前と値のペアにトークン化されます。Such an argument is also tokenized into a name/value pair. この場合の名前は、マークアップ拡張機能のサポート型の、パブリックに設定可能なプロパティの名前を指定します。The name in this case names a public settable property of the markup extension's support type. 名前付き引数の使用をサポートする場合は、これらのパブリックに設定可能なプロパティを用意する必要があります。If you intend to support named argument usage, you should provide these public settable properties. プロパティは、パブリックである限りは、継承プロパティを指定できます。The properties can be inherited properties as long as they remain public.

マークアップ拡張機能の実装からサービス プロバイダーのコンテキストにアクセスするAccessing Service Provider Context from a Markup Extension Implementation

使用可能なサービスは、すべての値コンバーターの場合と同じです。The services available are the same for any value converter. ただし、それぞれの値コンバーターがサービス コンテキストを受け取る方法が違います。The difference is in how each value converter receives the service context. サービスへのアクセスと、使用できるサービスについては、「 Type Converters and Markup Extensions for XAML」のトピックを参照してください。Accessing services and the services available are documented in the topic Type Converters and Markup Extensions for XAML.

マークアップ拡張機能のプロパティ要素の使用方法Property Element Usage of a Markup Extension

マークアップ拡張機能の使用のシナリオは、多くの場合、属性を使用したマークアップ拡張機能の使用を中心にして設計されます。The scenarios for markup extension usages are often designed around using the markup extension in attribute usage. ただし、プロパティ要素による使用をサポートするバッキング クラスを定義することも可能です。However, it is also potentially possible to define the backing class to support property element usage.

マークアップ拡張機能のプロパティ要素の使用をサポートするには、パラメーターなしのパブリックコンストラクターを定義します。To support property element usage of your markup extension, define a public parameterless constructor. これは、静的コンストラクターではなく、インスタンス コンストラクターにする必要があります。This should be an instance constructor not a static constructor. XAML プロセッサは通常、マークアップから処理するオブジェクト要素のパラメーターなしのコンストラクターを呼び出す必要があり、これにはオブジェクト要素としてマークアップ拡張クラスが含まれているため、これが必要になります。This is required because a XAML processor must generally invoke the parameterless constructor on any object element it processes from markup, and this includes markup extension classes as object elements. さらに複雑なシナリオとして、クラスに対して既定以外の構築パスを定義することもできます。For advanced scenarios, you can define non-default construction paths for classes. (詳細については、「 X:FactoryMethod ディレクティブ」を参照してください)。ただし、マークアップ拡張機能の目的では、これらのパターンを使用しないことをお勧めします。未加工のマークアップのデザイナーにとってもユーザーにとっても、使用パターンの検出が非常に困難になるからです。(For more information, see x:FactoryMethod Directive.) However, you should not use these patterns for markup extension purposes because this makes discovery of the usage pattern much more difficult, both for designers and for users of raw markup.

カスタム マークアップ拡張機能の属性設定Attributing for a Custom Markup Extension

デザイン環境と、特定の XAML オブジェクト ライターのシナリオのどちらをサポートするためにも、マークアップ拡張機能のサポート型にいくつかの CLR 属性を設定する必要があります。To support both design environments and certain XAML object writer scenarios, you should attribute a markup extension support type with several CLR attributes. これらの属性は、目的のマークアップ拡張機能の使用を報告します。These attributes report the intended markup extension usage.

MarkupExtensionReturnTypeAttribute は、 Type が返すオブジェクトの型の ProvideValue 情報を報告します。MarkupExtensionReturnTypeAttribute reports the Type information for the object type that ProvideValue returns. 純粋なシグネチャとしては、 ProvideValueObjectを返します。By its pure signature, ProvideValue returns Object. ただし、コンシューマーの種類によっては、戻り値の型についてさらに詳細な情報が必要になる場合があります。But various consumers might want more precise return type information. バインディングには、以下の項目が含まれます。This includes:

  • マークアップ拡張機能の使用に関して、型を認識したサポートを提供できるデザイナーや IDE を実現するための情報。Designers and IDEs, who might be able to provide type-aware support for markup extension usages.

  • ターゲット クラスに対する SetMarkupExtension ハンドラーの高度な実装のための情報。特定の既知の MarkupExtension 実装を名前で分岐して判別するのではなく、リフレクションに基づいてマークアップ拡張機能の戻り値の型を判別できるようになります。Advanced implementations of SetMarkupExtension handlers on target classes, which might rely on reflection to determine a markup extension's return type instead of branching on specific known MarkupExtension implementations by name.

マークアップ拡張機能の使用のシリアル化Serialization of Markup Extension Usages

XAML オブジェクト ライターによってマークアップ拡張機能の使用が処理され、 ProvideValueが呼び出されると、かつてマークアップ拡張機能の使用だったコンテキストは XAML ノード ストリームに残りますが、オブジェクト グラフには残りません。When a XAML object writer processes a markup extension usage and calls ProvideValue, the context for it previously being a markup extension usage persists in the XAML node stream but not in the object graph. オブジェクト グラフでは、値だけが保持されます。In the object graph, only the value is preserved. 元のマークアップ拡張機能の使用をシリアル化された出力として保持する、設計シナリオとしての必要性や他の理由がある場合は、読み込みパスの XAML ノード ストリームからマークアップ拡張機能の使用を追跡するための独自のインフラストラクチャを設計する必要があります。If you have design scenarios or other reasons for persisting the original markup extension usage into the serialized output, you must design your own infrastructure for tracking the markup extension usages from the load path XAML node stream. 読み込みパスからノード ストリームの要素を再作成し、ノード ストリームの該当する位置に値を代入しながら、それらを XAML ライターで再生して保存パスにシリアル化する、という動作を実装できます。You can implement behavior to recreate the elements of the node stream from the load path and play them back to XAML writers for serialization in the save path, substituting for the value in the appropriate position of the node stream.

XAML ノード ストリームのマークアップ拡張機能Markup Extensions in the XAML Node Stream

読み込みパスで XAML ノード ストリームを処理している場合、マークアップ拡張機能の使用は、オブジェクトとしてノード ストリーム内に登場します。If you are working with a XAML node stream on the load path, a markup extension usage appears in the node stream as an object.

マークアップ拡張機能の使用で位置指定引数が使用される場合、その使用は初期化の値が設定された開始オブジェクトとして表されます。If the markup extension usage uses positional arguments, it is represented as a start object with an initialization value. 大まかなテキスト表現では、ノード ストリームは次のようになります。As a rough text representation, the node stream resembles the following:

StartObject (XamlType はマークアップ拡張機能の定義の型であり、戻り値の型ではありません)StartObject (XamlType is the markup extension's definition type, not its return type)

StartMember ( XamlMember の名前は _InitializationText)StartMember (name of the XamlMember is _InitializationText)

Value (値は、途中に区切り記号を含む文字列形式の位置指定引数)Value (value is the positional arguments as a string including the intervening delimiters)

EndMember

EndObject

名前付き引数によるマークアップ拡張機能の使用は、その名前のメンバー (それぞれにテキスト文字列値が設定されている) を持つオブジェクトとして表されます。A markup extension usage with named arguments is represented as an object with members of the relevant names, each set with text string values.

実際にマークアップ拡張機能の ProvideValue 実装を呼び出すには、XAML スキーマ コンテキストが必要です。その呼び出しには、型マッピングと、マークアップ拡張機能のサポート型インスタンスの作成が必要であるからです。Actually invoking the ProvideValue implementation of a markup extension requires the XAML schema context because that requires type-mapping and creating a markup extension support type instance. これは、マークアップ拡張機能の使用が、既定の .NET Framework XAML サービスのノード ストリーム内でこのような形式に保たれている理由の 1 つです。多くの場合、読み込みパスのリーダー部分では、必要な XAML スキーマ コンテキストを利用できません。This is one reason why markup extension usages are preserved this way in the default .NET Framework XAML Services node streams - the reader part of a load path often does not have the necessary XAML schema context available.

保存パスで XAML ノード ストリームを処理している場合は、通常、シリアル化するオブジェクトが当初はマークアップ拡張機能の使用と ProvideValue の結果によって提供されたことを知らせる情報はオブジェクト グラフ表現の中に存在しません。If you are working with a XAML node stream on the save path, there generally is nothing present in an object graph representation that can inform you that the object to serialize was originally provided by a markup extension usage and a ProvideValue result. マークアップ拡張機能の使用をラウンドトリップさせ、オブジェクト グラフのその他の変化もキャプチャする必要があるシナリオでは、元の XAML 入力に由来するマークアップ拡張機能の使用の情報を保存するため、独自の手法を考案する必要があります。Scenarios that need to persist markup extension usages for round-tripping while also capturing other changes in the object graph must devise their own techniques for preserving the knowledge of a markup extension usage from the original XAML input. たとえば、マークアップ拡張機能の使用を復元するには、保存パス上のノード ストリームを処理してマークアップ拡張機能の使用を復元するか、元の XAML とラウンドトリップされた XAML に対して何らかのマージ処理を実行することができます。For example, to restore the markup extension usages, you may need to work with the node stream on the save path in order to restore markup extension usages, or perform some type of merge between the original XAML and the round-tripped XAML. WPF などの一部の XAML 実装フレームワークでは、中間の型 (式) を使用して、マークアップ拡張機能の使用が値を提供したケースを表す場合があります。Some XAML-implementing frameworks such as WPF use intermediate types (expressions) to help represent cases where markup extension usages provided the values.

関連項目See also