XAML の型コンバーターの概要

型コンバーターは、XAML マークアップの文字列をオブジェクト グラフの特定のオブジェクトに変換するオブジェクト ライターにロジックを提供します。 .NET Framework XAML サービスでは、型コンバーターは TypeConverter から派生したクラスである必要があります。 一部のコンバーターは XAML 保存パスもサポートしており、オブジェクトをシリアル化マークアップの文字列形式にシリアル化するために使用されます。 このトピックでは、XAML の型コンバーターがいつ、どのように起動されるかについて説明し、TypeConverter のメソッドのオーバーライドの実装についてアドバイスします。

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

  • 型変換の概念
  • 型コンバーターの実装
  • TypeConverterAttribute の適用
  • マークアップ拡張機能の実装からのサービス プロバイダー コンテキストへのアクセス
  • XAML ノード ストリームの型コンバーター
  • 関連トピック

型変換の概念

以降では、XAML で文字列を使用する方法や、.NET Framework XAML サービスのオブジェクト ライターで型コンバーターを使用して XAML ソースに含まれる文字列値の一部を処理する方法について、基本的な概念を説明します。

XAML と文字列値

XAML ファイルで属性値を設定するとき、その値の初期型は一般には文字列であり、XML では文字列属性値です。 Double などの他のプリミティブであっても、XAML プロセッサにとっては最初は文字列です。

ほとんどの場合、属性値を処理するために、XAML プロセッサは 2 つの情報を必要とします。 第 1 の情報は、設定するプロパティの値型です。 属性値を定義し、XAML で処理される文字列値はすべて、最終的にその型の値に変換 (解決) される必要があります。 その値が XAML パーサーで認識されるプリミティブ (数値など) である場合は、文字列の直接的な変換が試みられます。 属性の値が列挙体を参照している場合、指定された文字列で、その列挙体の名前付き定数に対する名前の一致がチェックされます。 値がパーサーで認識されるプリミティブでも列挙体の定数名でもない場合、適用される型は、変換される文字列に基づいた値または参照を提供できる必要があります。

メモメモ

XAML 言語ディレクティブでは、型コンバーターは使用されません。

型コンバーターとマークアップ拡張機能

プロパティの型やその他の考慮事項を確認する前に、XAML プロセッサによってマークアップ拡張機能の使用方法を処理する必要があります。 たとえば、通常は属性として設定されるプロパティに型変換が設定され、特定のケースでマークアップ拡張機能の使用方法によって設定が行われる場合、マークアップ拡張機能の動作が最初に処理されます。 マークアップ拡張機能が必要となる典型的な状況の 1 つとして、既存のオブジェクトを参照する場合が挙げられます。 このシナリオでは、ステートレスの型コンバーターは新しいインスタンスしか生成できませんが、これは望ましくない場合があります。 マークアップ拡張機能の詳細については、「XAML のマークアップ拡張機能の概要」を参照してください。

ネイティブな型コンバーター

WPF および .NET XAML サービスの実装には、ネイティブな型変換処理を定義している CLR 型があります。ただし、それらの CLR 型は、これまではプリミティブ型として扱われませんでした。 このような型の例として、DateTime が挙げられます。 その理由の 1 つは、.NET Framework アーキテクチャがどのように機能するかに基づいています。DateTime 型は、.NET の最も基本的なライブラリである mscorlib で定義されています。 DateTime の属性は、依存関係を伴う他のアセンブリの属性では指定できないため (TypeConverterAttribute は System の属性)、属性を使用した通常の型コンバーター検出機構は使用できません。 代わりに、このようなネイティブな処理が必要な型の一覧が XAML パーサーに用意されており、XAML パーサーは、これらの型を通常のプリミティブ型と同様の方法で処理します。 DateTime の場合、この処理は Parse への呼び出しに相当します。

型コンバーターの実装

以降では、TypeConverter クラスの API について説明します。

TypeConverter

.NET Framework XAML サービスでは、XAML で使用されるすべての型コンバーターは、TypeConverter 基本クラスからの派生クラスです。 TypeConverter クラスは、XAML が登場する前のバージョンの .NET Framework にも用意されていました。TypeConverter の本来のシナリオの 1 つは、ビジュアルなデザイナーでプロパティ エディターの文字列変換に対応することでした。

XAML では、TypeConverter の役割は強化されました。 XAML の目的上、TypeConverter は特定の文字列への変換と文字列からの変換に対応する基本クラスになります。 文字列からの変換により、XAML の文字列属性値の解析ができるようになります。 また、文字列への変換により、シリアル化を目的として特定のオブジェクト プロパティの実行時の値を XAML の属性に再変換できるようになります。

TypeConverter には、XAML の処理を目的とした文字列の変換に関係する、次の 4 つのメンバーが定義されています。

このメンバーのうち、最も重要なメソッドは ConvertFrom であり、入力文字列を必要なオブジェクトの種類に変換します。 ConvertFrom メソッドを実装して、さらに広範な型をコンバーターの目的の型に変換できます。 したがって、実行時の変換に対するサポートなど、XAML 以外の目的にも使用できます。 ただし、XAML の用途では、String の入力を処理できるコード パスのみが重要になります。

次に重要なメソッドは ConvertTo です。 アプリケーションをマークアップ表現に変換する場合 (アプリケーションを XAML でファイルとして保存する場合など)、ConvertTo は、マークアップ表現を生成する XAML テキスト ライターを使用する大規模なシナリオで使用されます。 この場合、XAML の重要なコード パスは、呼び出し元が String の destinationType を渡すときです。

CanConvertToCanConvertFrom は、TypeConverter 実装の機能をサービスが照会するときに使用されるサポート メソッドです。 これらのメソッドは、コンバーターの対応する変換メソッドが、型固有の状況をサポートしている場合に、true を返すように実装する必要があります。 XAML では、通常、String 型について true が返されます。

カルチャ情報と XAML の型コンバーター

TypeConverter の実装には、変換に有効な文字列の構成内容について独自に解釈できます。また、パラメーターとして渡された型説明を使用したり無視したりすることもできます。 カルチャと XAML の型変換については重要な考慮事項があります。ローカライズ可能な文字列を属性値として使うことは XAML でサポートされていますが、このようなローカライズ可能な文字列を特定のカルチャ要件を持つ型コンバーターの入力として使うことはできません。 この制限の理由としては、XAML 属性値の型コンバーターには、必ず特定の言語の XAML 処理動作 (en-US カルチャを使用) が組み込まれていることが挙げられます。 この制限に関する設計上の理由の詳細については、XAML 言語仕様 (「[MS-XAML]」) または「WPF のグローバリゼーションおよびローカリゼーションの概要」を参照してください。

カルチャが問題となる例として、一部のカルチャで文字列形式の数値の小数点記号に、ピリオドではなくコンマが使用されていることが挙げられます。 このような使用方法では、既存の型コンバーターはその多くがコンマを区切り記号として使用しているので、動作が競合することになります。 周囲の XAML で xml:lang を使用してカルチャを指定しても、この問題は解決されません。

ConvertFrom の実装

XAML をサポートする TypeConverter の実装としてコンバーターを使用できるようにするためには、そのコンバーターの ConvertFrom メソッドが、value パラメーターとして文字列を受け入れる必要があります。 文字列が有効な形式であり、TypeConverter 実装で変換できる場合、返されるオブジェクトは、プロパティで予想される型へのキャストをサポートしている必要があります。 それ以外の場合は、ConvertFrom 実装は null を返す必要があります。

TypeConverter の実装は、変換に有効な文字列の構成内容について独自に解釈できます。また、パラメーターとして渡された型の説明やカルチャ コンテキストを使用したり無視したりすることもできます。 ただし、WPF XAML 処理が、値を型説明コンテキストに渡さない場合があり、xml:lang に基づくカルチャを渡さない場合もあります。

メモメモ

文字列の書式の要素として、中かっこ ({}) (具体的には左中かっこ ({)) は使用しないでください。これらの文字は、マークアップ拡張シーケンスの開始および終了を示す文字として予約されています。

型コンバーターが .NET Framework XAML サービスのオブジェクト ライターから XAML サービスへのアクセス許可を必要とするが、コンテキストに対する GetService の呼び出しがそのサービスを返さない場合については、例外をスローするのが適切です。

ConvertTo の実装

ConvertTo はシリアル化のサポートで使用される場合があります。 ConvertTo を使用したカスタム型およびその型コンバーターのシリアル化のサポートは、絶対要件ではありません。 ただし、コントロールを実装する場合、またはクラスの機能または設計の一部としてシリアル化を使用する場合は、ConvertTo を実装する必要があります。

XAML をサポートする TypeConverter の実装としてコンバーターを使用できるようにするためには、そのコンバーターの ConvertTo メソッドが、value パラメーターとして、サポートされる型のインスタンス (または値) を受け入れる必要があります。 destinationType パラメーターが String 型の場合は、返されるオブジェクトは String にキャストできる必要があります。 返される文字列は、value のシリアル化された値を表す必要があります。 理想としては、選択するシリアル化形式は、その文字列が同じコンバーターの ConvertFrom の実装に渡された場合に、情報の大きな損失が発生することなく、同じ値を生成できる必要があります。

値をシリアル化できない場合、またはコンバーターがシリアル化をサポートしていない場合は、ConvertTo の実装は null を返す必要があり、例外をスローできます。 ただし、例外をスローする場合は、CanConvertTo の実装の一部として変換を使用できないことを示すことにより、事前に CanConvertTo を確認して例外の発生を回避するというベスト プラクティスに対応する必要があります。

destinationType パラメーターが String 型でない場合は、独自のコンバーターの処理を選択できます。 通常は、基本実装の処理 (基本の ConvertTo では特定の例外が発生する) に戻ります。

型コンバーターが .NET Framework XAML サービスのオブジェクト ライターから XAML サービスへのアクセス許可を必要とするが、コンテキストに対する GetService の呼び出しがそのサービスを返さない場合については、例外をスローするのが適切です。

CanConvertFrom の実装

CanConvertFrom の実装は、String 型の sourceType に対しては true を返し、それ以外の場合は基本実装に任せます。 CanConvertFrom から例外をスローしないでください。

CanConvertTo の実装

CanConvertTo の実装は、destinationType が String 型の場合には true を返し、それ以外の場合は基本実装に任せるようにする必要があります。 CanConvertTo から例外をスローしないでください。

TypeConverterAttribute の適用

カスタムの型コンバーターがカスタム クラス用の型コンバーターとして .NET Framework XAML サービスによって使用されるようにするには、.NET Framework attribute TypeConverterAttribute をクラス定義に適用する必要があります。 属性で指定する ConverterTypeName は、カスタム型コンバーターの型名である必要があります。 この属性を適用すると、プロパティの型としてカスタム クラス型が使用される場合に、XAML プロセッサが値を処理する際、入力文字列を処理して、オブジェクト インスタンスを返すことができます。

また、プロパティごとに型コンバーターを提供することもできます。 クラス定義に .NET Framework attribute TypeConverterAttribute を適用する代わりに、プロパティ定義 (メイン定義内の get/set 実装ではなくメイン定義自体) に適用します。 プロパティの型は、カスタム型コンバーターによって処理される型と一致する必要があります。 この属性を適用すると、そのプロパティの値を XAML プロセッサが処理する際に、入力文字列を処理して、オブジェクト インスタンスを返すことができます。 プロパティごとの型コンバーターは、Microsoft .NET Framework のプロパティ型を使用する場合、またはクラス定義を制御できず、TypeConverterAttribute を適用できない他のライブラリのプロパティ型を使用する場合に、特に役立ちます。

アタッチされたカスタム メンバーの型変換動作を割り当てるには、アタッチされたメンバーの実装パターンの Get アクセサー メソッドに TypeConverterAttribute を適用します。

マークアップ拡張機能の実装からのサービス プロバイダー コンテキストへのアクセス

使用できるサービスは、どの値コンバーターも同じです。 ただし、それぞれの値コンバーターがサービス コンテキストを受信する方法が違います。 サービスへのアクセスと、使用できるサービスについては、「XAML の型コンバーターおよびマークアップ拡張機能」のトピックを参照してください。

XAML ノード ストリームの型コンバーター

XAML ノード ストリームを操作している場合、型コンバーターのアクションや最終結果はまだ実行されていません。 読み込みパスでは、読み込むために最終的に型変換する必要がある属性文字列は、開始メンバーおよび終了メンバー内ではテキスト値のままです。 この操作のために最終的に必要になる型コンバーターは、XamlMember.TypeConverter プロパティを使用することで判別できます。 ただし、XamlMember.TypeConverter から有効な値を取得するには、基になるメンバー (メンバーが使用するオブジェクト値の型) を介してこのような情報にアクセスできる XAML スキーマ コンテキストに依存することになります。 型変換の動作を呼び出すためにも、型マッピングと、コンバーター インスタンスの作成が必要であるため、XAML スキーマ コンテキストも必要になります。

参照

参照

TypeConverterAttribute

概念

XAML の概要 (WPF)

その他の技術情報

XAML の型コンバーターおよびマークアップ拡張機能