WPF における XAML とカスタム クラスXAML and Custom Classes for WPF

共通言語ランタイム (CLR) フレームワークで実装されている XAML は、任意の共通言語ランタイム (CLR) 言語でカスタムクラスまたは構造体を定義し、そのクラスに XAML マークアップを使用してアクセスする機能をサポートしています。XAML as implemented in common language runtime (CLR) frameworks supports the ability to define a custom class or structure in any common language runtime (CLR) language, and then access that class using XAML markup. 同じマークアップファイル内でWindows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)定義された型とカスタム型の組み合わせを使用できます。通常は、カスタム型を XAML 名前空間プレフィックスにマップします。You can use a mixture of Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)-defined types and your custom types within the same markup file, typically by mapping the custom types to a XAML namespace prefix. このトピックでは、カスタムクラスが XAML 要素として使用できるようにするために満たす必要がある要件について説明します。This topic discusses the requirements that a custom class must satisfy to be usable as a XAML element.

アプリケーションまたはアセンブリのカスタムクラスCustom Classes in Applications or Assemblies

XAML で使用されるカスタムクラスは、分離コード内、またはプライマリWindows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)アプリケーションを生成する他のコード内、またはクラスライブラリとして使用される実行可能ファイルや DLL などの別のアセンブリ内のクラスとして定義できます。Custom classes that are used in XAML can be defined in two distinct ways: within the code-behind or other code that produces the primary Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) application, or as a class in a separate assembly, such as an executable or DLL used as a class library. これらの各方法には、特定の利点と欠点があります。Each of these approaches has particular advantages and disadvantages.

  • クラスライブラリを作成する利点は、このようなカスタムクラスをさまざまなアプリケーション間で共有できることです。The advantage of creating a class library is that any such custom classes can be shared across many different possible applications. また、別のライブラリを使用すると、アプリケーションのバージョン管理の問題を簡単に制御でき、意図したクラスの使用が XAML ページのルート要素として使用されるクラスの作成が簡単になります。A separate library also makes versioning issues of applications easier to control, and simplifies creating a class where the intended class usage is as a root element on a XAML page.

  • アプリケーションでカスタムクラスを定義する利点は、この手法が比較的軽量であり、メインアプリケーションの実行可能ファイルを超える個別のアセンブリを導入した場合に発生する配置およびテストの問題を最小限に抑えることです。The advantage of defining the custom classes in the application is that this technique is relatively lightweight and minimizes the deployment and testing issues encountered when you introduce separate assemblies beyond the main application executable.

  • 同じまたは別のアセンブリで定義されているかどうかにかかわらず、XAML で要素として使用するためには、カスタムクラスを CLR 名前空間と XML 名前空間の間でマップする必要があります。Whether defined in the same or different assembly, custom classes need to be mapped between CLR namespace and XML namespace in order to be used in XAML as elements. WPF xaml の Xaml 名前空間と名前空間のマッピング」を参照してください。See XAML Namespaces and Namespace Mapping for WPF XAML.

XAML 要素としてのカスタムクラスの要件Requirements for a Custom Class as a XAML Element

オブジェクト要素としてインスタンス化できるようにするには、クラスが次の要件を満たしている必要があります。In order to be able to be instantiated as an object element, your class must meet the following requirements:

  • カスタムクラスはパブリックであり、既定の (パラメーターなしの) パブリックコンストラクターをサポートしている必要があります。Your custom class must be public and support a default (parameterless) public constructor. (構造に関する注意事項については、次のセクションを参照してください)。(See following section for notes regarding structures.)

  • カスタムクラスを入れ子にしたクラスにすることはできません。Your custom class must not be a nested class. 入れ子になったクラスと CLR の一般的な使用構文の "ドット" WPFWPFは、添付プロパティなどの他の機能や XAML 機能に影響します。Nested classes and the "dot" in their general CLR usage syntax interfere with other WPFWPF and/or XAML features such as attached properties.

オブジェクトの要素の構文を有効にするだけでなく、オブジェクトの定義では、そのオブジェクトを値の型として使用する他のパブリックプロパティのプロパティ要素構文を有効にすることもできます。In addition to enabling object element syntax, your object definition also enables property element syntax for any other public properties that take that object as the value type. これは、オブジェクトをオブジェクト要素としてインスタンス化できるようになり、そのようなプロパティのプロパティ要素の値を埋めることができるためです。This is because the object can now be instantiated as an object element and can fill the property element value of such a property.

構造体Structures

カスタム型として定義する構造体は、のWPFWPF XAML で常に構築できます。これは、すべてのプロパティ値を既定値に初期化する構造体のパラメーターなしのコンストラクターが CLR コンパイラによって暗黙的に作成されるためです。Structures that you define as custom types are always able to be constructed in XAML in WPFWPF .This is because the CLR compilers implicitly create a parameterless constructor for a structure that initializes all property values to their defaults. 場合によっては、構造体の既定の構築動作やオブジェクト要素の使用が望ましくないことがあります。In some cases, the default construction behavior and/or object element usage for a structure is not desirable. これは、構造体が値を結合することを意図しており、概念的には共用体として機能します。この場合、含まれる値は相互に排他的な解釈を持つ可能性があるため、そのプロパティは設定できません。This might be because the structure is intended to fill values and function conceptually as a union, where the values contained might have mutually exclusive interpretations and thus none of its properties are settable. このWPFWPFような構造の例とGridLengthしては、があります。A WPFWPF example of such a structure is GridLength. 通常、このような構造体では、構造体の値のさまざまな解釈やモードを作成する文字列表記規則を使用して、値を属性形式で表現できるように、型コンバーターを実装する必要があります。Generally, such structures should implement a type converter such that the values can be expressed in attribute form, using string conventions that create the different interpretations or modes of the structure's values. また、構造体は、パラメーターなしのコンストラクターを使用してコードを構築する場合にも同様の動作を公開する必要があります。The structure should also expose similar behavior for code construction through a non-parameterless constructor.

XAML 属性としてのカスタムクラスのプロパティの要件Requirements for Properties of a Custom Class as XAML Attributes

プロパティは、値渡しの型 (プリミティブなど) を参照するか、XAML プロセッサがアクセスできるパラメーターなしのコンストラクターまたは専用の型コンバーターを持つ型のクラスを使用する必要があります。Properties must reference a by-value type (such as a primitive), or use a class for type that has either a parameterless constructor or a dedicated type converter that a XAML processor can access. CLR xaml 実装では、xaml プロセッサは、言語プリミティブのネイティブサポートを通じて、またはバッキング型TypeConverterAttribute定義の型またはメンバーへのアプリケーションを使用して、このようなコンバーターを検出します。In the CLR XAML implementation, XAML processors either find such converters through native support for language primitives, or through application of TypeConverterAttribute to a type or member in backing type definitions

また、プロパティは抽象クラス型またはインターフェイスを参照できます。Alternatively, the property may reference an abstract class type, or an interface. 抽象クラスまたはインターフェイスの場合、XAML の解析に期待されるのは、インターフェイスを実装する実際のクラスインスタンス、または抽象クラスから派生した型のインスタンスをプロパティ値に入力する必要があることです。For abstract classes or interfaces, the expectation for XAML parsing is that the property value must be filled with practical class instances that implement the interface, or instances of types that derive from the abstract class.

プロパティは抽象クラスで宣言できますが、抽象クラスから派生した実用的なクラスでのみ設定できます。Properties can be declared on an abstract class, but can only be set on practical classes that derive from the abstract class. これは、クラスの object 要素を作成するときに、クラスのパラメーターなしのパブリックコンストラクターが必要になるためです。This is because creating the object element for the class at all requires a public parameterless constructor on the class.

TypeConverter Enabled 属性の構文TypeConverter Enabled Attribute Syntax

クラスレベルで専用の属性付きの型コンバーターを指定した場合、適用される型変換によって、その型をインスタンス化する必要がある任意のプロパティの属性構文が有効になります。If you provide a dedicated, attributed type converter at the class level, the applied type conversion enables attribute syntax for any property that needs to instantiate that type. 型コンバーターは、型のオブジェクト要素の使用を有効にしません。オブジェクト要素の使用を有効にできるのは、その型にパラメーターなしのコンストラクターが存在する場合だけです。A type converter does not enable object element usage of the type; only the presence of a parameterless constructor for that type enables object element usage. そのため、型コンバーターが有効になっているプロパティは、通常、プロパティ構文では使用できません。ただし、型自体がオブジェクト要素構文もサポートしている場合を除きます。Therefore, properties that are type-converter enabled are generally speaking not usable in property syntax, unless the type itself also supports object element syntax. 例外として、プロパティ要素構文を指定できますが、property 要素には文字列が含まれています。The exception to this is that you can specify a property element syntax, but have the property element contain a string. この使用法は、実質的に属性の構文の使用に相当します。このような使用方法は、属性値のより堅牢な空白処理が必要な場合を除き、一般的ではありません。That usage is really essentially equivalent to an attribute syntax usage, and such a usage is not common unless there is a need for more robust white-space handling of the attribute value. たとえば、次の例は、文字列を受け取るプロパティ要素の使用法と、同等の属性の使用法を示しています。For example, the following is a property element usage that takes a string, and the attribute usage equivalent:

<Button>Hallo!
  <Button.Language>
    de-DE
  </Button.Language>
</Button>
<Button Language="de-DE">Hallo!</Button>

属性構文が許可されるプロパティの例ですが、object 要素を含む property 要素構文は、型をCursor受け取るさまざまなプロパティです。Examples of properties where attribute syntax is allowed but property element syntax that contains an object element is disallowed through XAML are various properties that take the Cursor type. クラスCursorには専用の型コンバーター CursorConverterがありますが、パラメーターなしのコンストラクターは公開Cursorされないため、プロパティを設定できるのは、 Cursor実際の型が参照型である場合でも属性構文を使用してのみです。The Cursor class has a dedicated type converter CursorConverter, but does not expose a parameterless constructor, so the Cursor property can only be set through attribute syntax even though the actual Cursor type is a reference type.

プロパティごとの型コンバーターPer-Property Type Converters

また、プロパティ自体は、プロパティレベルで型コンバーターを宣言できます。Alternatively, the property itself may declare a type converter at the property level. これにより、適切な型に基づいて、属性の受信文字列値をConvertFrom操作の入力として処理することにより、プロパティの型のオブジェクトをインスタンス化する "ミニ言語" を有効にできます。This enables a "mini language" that instantiates objects of the type of the property inline, by processing incoming string values of the attribute as input for a ConvertFrom operation based on the appropriate type. これは通常、XAML でプロパティの設定を有効にする唯一の手段としてではなく、便宜的なアクセサーを提供するために行われます。Typically this is done to provide a convenience accessor, and not as the sole means to enable setting a property in XAML. ただし、パラメーターなしのコンストラクターまたは属性付きの型コンバーターを提供しない既存の CLR 型を使用する属性には、型コンバーターを使用することもできます。However, it is also possible to use type converters for attributes where you want to use existing CLR types that do not supply either a parameterless constructor or an attributed type converter. API のWPFWPF例としては、 CultureInfo型を受け取る特定のプロパティがあります。Examples from the WPFWPF API are certain properties that take the CultureInfo type. この例ではWPFWPF 、既存の Microsoft .NET Framework CultureInfo型を使用して、以前のバージョンのフレームワークで使用されていた互換性CultureInfoと移行のシナリオをより適切に解決しましたが、型は必要なをサポートしていませんでした。コンストラクターまたは型レベルの型変換は、XAML プロパティ値として直接使用できます。In this case, WPFWPF used the existing Microsoft .NET Framework CultureInfo type to better address compatibility and migration scenarios that were used in earlier versions of frameworks, but the CultureInfo type did not support the necessary constructors or type-level type conversion to be usable as a XAML property value directly.

XAML を使用するプロパティを公開するときは常に、特にコントロールの作成者である場合は、依存関係プロパティを使用してそのプロパティをバックアップすることを強くお勧めします。Whenever you expose a property that has a XAML usage, particularly if you are a control author, you should strongly consider backing that property with a dependency property. これは、バッキングを使用Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) DependencyPropertyしてパフォーマンスを向上できるため、XAML プロセッサの既存の実装を使用する場合に特に当てはまります。This is particularly true if you use the existing Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) implementation of the XAML processor, because you can improve performance by using DependencyProperty backing. 依存関係プロパティは、ユーザーが XAML アクセス可能なプロパティに対して期待するプロパティのプロパティシステム機能を公開します。A dependency property will expose property system features for your property that users will come to expect for a XAML accessible property. これには、アニメーション、データバインディング、スタイルのサポートなどの機能が含まれます。This includes features such as animation, data binding, and style support. 詳細については、「カスタム依存関係プロパティ」および「 XAML 読み込みと依存関係プロパティ」を参照してください。For more information, see Custom Dependency Properties and XAML Loading and Dependency Properties.

型コンバーターの記述と属性Writing and Attributing a Type Converter

場合によっては、プロパティ型TypeConverterの型変換を提供するために、カスタム派生クラスを記述する必要があります。You occasionally will need to write a custom TypeConverter derived class to provide type conversion for your property type. から派生し、xaml の使用をサポートできる型コンバーターを作成する方法、およびを適用TypeConverterAttributeする方法については、「 TypeConverters and XAML」を参照してください。For instructions on how to derive from and create a type converter that can support XAML usages, and how to apply the TypeConverterAttribute, see TypeConverters and XAML.

カスタムクラスのイベントに対する XAML イベントハンドラー属性構文の要件Requirements for XAML Event Handler Attribute Syntax on Events of a Custom Class

CLR イベントとして使用できるようにするには、イベントを、パラメーターなしのコンストラクターをサポートするクラスのパブリックイベントとして、または派生クラスでイベントにアクセスできる抽象クラスで公開する必要があります。To be usable as a CLR event, the event must be exposed as a public event on a class that supports a parameterless constructor, or on an abstract class where the event can be accessed on derived classes. 簡単にルーティングイベントとして使用するためには、clr イベントに明示addremoveなメソッドとメソッドを実装する必要があります。 RemoveHandlerこのメソッドは、clr イベントAddHandlerシグネチャのハンドラーを追加および削除し、それらのハンドラーをに転送します。メソッド.In order to be used conveniently as a routed event, your CLR event should implement explicit add and remove methods, which add and remove handlers for the CLR event signature and forward those handlers to the AddHandler and RemoveHandler methods. これらのメソッドは、イベントがアタッチされているインスタンス上のルーティングイベントハンドラーストアにハンドラーを追加または削除します。These methods add or remove the handlers to the routed event handler store on the instance that the event is attached to.

注意

を使用してAddHandler、ルーティングイベントのハンドラーを直接登録したり、ルーティングイベントを公開する CLR イベントを意図的に定義したりすることはできません。It is possible to register handlers directly for routed events using AddHandler, and to deliberately not define a CLR event that exposes the routed event. 通常、この方法は推奨されません。イベントはハンドラーをアタッチするための XAML 属性構文を有効にせず、生成されたクラスはその型の機能の透明度の低い XAML ビューを提供します。This is not generally recommended because the event will not enable XAML attribute syntax for attaching handlers, and your resulting class will offer a less transparent XAML view of that type's capabilities.

コレクションのプロパティの書き込みWriting Collection Properties

コレクション型を受け取るプロパティには、コレクションに追加されるオブジェクトを指定できるようにする XAML 構文があります。Properties that take a collection type have a XAML syntax that enables you to specify objects that are added to the collection. この構文には、2つの注目すべき機能があります。This syntax has two notable features.

  • オブジェクト要素構文では、コレクションオブジェクトであるオブジェクトを指定する必要はありません。The object that is the collection object does not need to be specified in object element syntax. コレクション型を受け取る XAML でプロパティを指定するたびに、コレクション型の存在が暗黙的になります。The presence of that collection type is implicit whenever you specify a property in XAML that takes a collection type.

  • マークアップのコレクションプロパティの子要素は、コレクションのメンバーになるように処理されます。Child elements of the collection property in markup are processed to become members of the collection. 通常、コレクションのメンバーへのコードアクセスはAdd、などのリスト/ディクショナリメソッド、またはインデクサーを使用して実行されます。Ordinarily, the code access to the members of a collection is performed through list/dictionary methods such as Add, or through an indexer. ただし、XAML 構文では、メソッドまたはインデクサーはサポートされません (例外:XAML 2009 ではメソッドがサポートされますが、XAML 2009 を使用すると WPF の使用を制限できます。「 XAML 2009 言語機能」を参照してください)。But XAML syntax does not support methods or indexers (exception: XAML 2009 can support methods, but using XAML 2009 restricts the possible WPF usages; see XAML 2009 Language Features). コレクションは、要素のツリーを構築するための非常に一般的な要件であり、宣言型の XAML でこれらのコレクションを設定する方法が必要です。Collections are obviously a very common requirement for building a tree of elements, and you need some way to populate these collections in declarative XAML. したがって、コレクションプロパティの子要素は、コレクションプロパティの型の値であるコレクションに追加することで処理されます。Therefore, child elements of a collection property are processed by adding them to the collection that is the collection property type value.

.NET Framework XAML サービスの実装であるため、WPF XAML プロセッサは、コレクションプロパティを構成するために次の定義を使用します。The .NET Framework XAML Services implementation and thus the WPF XAML processor uses the following definition for what constitutes a collection property. プロパティのプロパティの型は、次のいずれかを実装する必要があります。The property type of the property must implement one of the following:

CLR の各型にはAddメソッドがあります。このメソッドは、オブジェクトグラフの作成時に、XAML プロセッサによって使用され、基になるコレクションに項目を追加します。Each of these types in CLR has an Add method, which is used by the XAML processor to add items to the underlying collection when creating the object graph.

注意

ジェネリックListおよびDictionaryインターフェイスWPFWPF (IList<T>および) は、XAML プロセッサによるコレクションの検出ではサポートされていません。 IDictionary<TKey,TValue>The generic List and Dictionary interfaces (IList<T> and IDictionary<TKey,TValue>) are not supported for collection detection by the WPFWPF XAML processor. ただし、 List<T>クラスは、直接実装するかDictionary<TKey,TValue> 、基底クラスIDictionaryとしてIList直接実装するため、基底クラスとして使用できます。However, you can use the List<T> class as a base class, because it implements IList directly, or Dictionary<TKey,TValue> as a base class, because it implements IDictionary directly.

コレクションを受け取るプロパティを宣言するときは、そのプロパティ値が型の新しいインスタンスでどのように初期化されるかに注意してください。When you declare a property that takes a collection, be cautious about how that property value is initialized in new instances of the type. プロパティを依存関係プロパティとして実装していない場合は、コレクション型コンストラクターを呼び出すバッキングフィールドをプロパティに使用するのが適切です。If you are not implementing the property as a dependency property, then having the property use a backing field that calls the collection type constructor is adequate. プロパティが依存関係プロパティの場合は、既定の型コンストラクターの一部としてコレクションプロパティを初期化する必要がある場合があります。If your property is a dependency property, then you may need to initialize the collection property as part of the default type constructor. これは、依存関係プロパティの既定値がメタデータから取得されるためです。通常は、コレクションプロパティの初期値を静的な共有コレクションにする必要がありません。This is because a dependency property takes its default value from metadata, and you typically do not want the initial value of a collection property to be a static, shared collection. 含まれている型のインスタンスごとにコレクションインスタンスが存在している必要があります。There should be a collection instance per each containing type instance. 詳細については、「カスタム依存関係プロパティ」を参照してください。For more information, see Custom Dependency Properties.

コレクションプロパティのカスタムコレクション型を実装できます。You can implement a custom collection type for your collection property. コレクションプロパティの暗黙的な処理により、カスタムコレクション型は、暗黙的に XAML で使用するために、パラメーターなしのコンストラクターを提供する必要がありません。Because of implicit collection property treatment, the custom collection type does not need to provide a parameterless constructor in order to be used in XAML implicitly. ただし、必要に応じて、コレクション型のパラメーターなしのコンストラクターを指定することもできます。However, you can optionally provide a parameterless constructor for the collection type. これは、有益な方法です。This can be a worthwhile practice. パラメーターなしのコンストラクターを指定しない限り、コレクションをオブジェクト要素として明示的に宣言することはできません。Unless you do provide a parameterless constructor, you cannot explicitly declare the collection as an object element. マークアップの作成者は、マークアップスタイルに関係なく、明示的なコレクションを表示することを好む場合があります。Some markup authors might prefer to see the explicit collection as a matter of markup style. また、パラメーターなしのコンストラクターを使用すると、コレクション型をプロパティ値として使用する新しいオブジェクトを作成するときに初期化要件を簡略化できます。Also, a parameterless constructor can simplify the initialization requirements when you create new objects that use your collection type as a property value.

宣言 (XAML コンテンツプロパティを)Declaring XAML Content Properties

XAML 言語は、 XAMLXAMLコンテンツプロパティの概念を定義します。The XAML language defines the concept of a XAMLXAML content property. オブジェクト構文で使用できる各クラスは、XAML コンテンツプロパティを1つだけ持つことができます。Each class that is usable in object syntax can have exactly one XAML content property. クラスの XAML コンテンツプロパティとなるプロパティを宣言するにはContentPropertyAttribute 、をクラス定義の一部として適用します。To declare a property to be the XAML content property for your class, apply the ContentPropertyAttribute as part of the class definition. 属性のとしてName 、目的の XAML コンテンツプロパティの名前を指定します。Specify the name of the intended XAML content property as the Name in the attribute. プロパティは、のようなPropertyInfoリフレクションコンストラクトとしてではなく、名前で文字列として指定されます。The property is specified as a string by name, not as a reflection construct such as PropertyInfo.

XAML コンテンツプロパティとなるコレクションプロパティを指定できます。You can specify a collection property to be the XAML content property. この結果、そのプロパティが使用されます。これにより、オブジェクト要素には、コレクションオブジェクトの要素またはプロパティ要素タグを介在させることなく、1つまたは複数の子要素を含めることができます。This results in a usage for that property whereby the object element can have one or more child elements, without any intervening collection object elements or property element tags. これらの要素は、XAML コンテンツプロパティの値として処理され、バッキングコレクションインスタンスに追加されます。These elements are then treated as the value for the XAML content property and added to the backing collection instance.

一部の既存の XAML コンテンツプロパティは、のObjectプロパティの型を使用します。Some existing XAML content properties use the property type of Object. これにより、などのプリミティブ値を取得したり、 String 1 つの参照オブジェクト値を取得したりできる XAML コンテンツプロパティが有効になります。This enables a XAML content property that can take primitive values such as a String as well as taking a single reference object value. このモデルに従う場合は、型の決定と、可能な型の処理が型によって行われます。If you follow this model, your type is responsible for type determination as well as the handling of possible types. Objectコンテンツの種類の一般的な理由は、オブジェクトコンテンツを文字列として追加する単純な方法 (既定のプレゼンテーション処理を受け取る)、または既定以外のプレゼンテーションを指定するオブジェクトのコンテンツを追加する高度な方法の両方をサポートすることです。追加データ。The typical reason for an Object content type is to support both a simple means of adding object content as a string (which receives a default presentation treatment), or an advanced means of adding object content that specifies a non-default presentation or additional data.

XAML のシリアル化Serializing XAML

コントロールの作成者である場合など、特定のシナリオでは、XAML でインスタンス化できるすべてのオブジェクト表現を、同等の XAML マークアップにシリアル化することもできます。For certain scenarios, such as if you are a control author, you may also want to assure that any object representation that can be instantiated in XAML can also be serialized back to equivalent XAML markup. このトピックでは、シリアル化の要件については説明しません。Serialization requirements are not described in this topic. コントロールの作成の概要」と「要素ツリーとシリアル化」を参照してください。See Control Authoring Overview and Element Tree and Serialization.

関連項目See also