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

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

型変換の概念

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

XAML と文字列値

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

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

Note

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

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

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

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

Windows Presentation Foundation (WPF) と .NET XAML サービスの実装には、ネイティブな型変換処理を持つ特定の CLR 型があります。 ただし、それらの CLR 型は慣例としてプリミティブとは見なされません。 このような型の例として、 DateTimeが挙げられます。 この理由の 1 つは、.NET Framework のアーキテクチャがどのように機能するかにあります。 DateTime 型は、.NET の最も基本的なライブラリである mscorlib で定義されています。 従属関係が発生する別のアセンブリからの属性を使用して、DateTime の属性を設定することはできません (TypeConverterAttribute は System から)。 したがって、属性の設定による通常の型コンバーター検出メカニズムはサポートできません。 代わりに、XAML パーサーは、ネイティブな処理が必要な型の一覧を保持し、それらの型を通常のプリミティブの処理と類似した方法で処理します。 DateTimeの場合、その処理には Parseの呼び出しが含まれます。

型コンバーターの実装

以下のセクションで、 TypeConverter クラスの API について説明します。

TypeConverter

.NET 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 にとって重要なコード パスは、呼び出し元が destinationTypeStringを渡す時です。

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

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

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

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

ConvertFrom の実装

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

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

Note

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

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

ConvertTo の実装

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

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

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

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

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

CanConvertFrom の実装

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

CanConvertTo の実装

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

TypeConverterAttribute の適用

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

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

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

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

使用可能なサービスは、すべての値コンバーターの場合と同じです。 ただし、それぞれの値コンバーターがサービス コンテキストを受け取る方法が違います。 サービスへのアクセスと、使用できるサービスについては、「 Type Converters and Markup Extensions for XAML」のトピックをご覧ください。

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

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

関連項目