Windows フォーム デザイナーのフレームワークと WPF デザイナーのフレームワークの比較
WPF デザイナーのアーキテクチャは、IComponent インターフェイスと System.ComponentModel 名前空間で識別される Windows フォーム デザイナーのアーキテクチャとは大きく異なります。 Windows フォーム コントロールのカスタム デザイン時実装を作成したことがあるユーザーは、WPF デザイナー アーキテクチャの使いやすさと拡張しやすさに気付くでしょう。
WPF デザイナー アーキテクチャは、Windows フォーム デザイナーのオブジェクト モデルから TypeConverter クラスと TypeDescriptor クラスを保持します。 それを除くと、WPF デザイナー アーキテクチャはほとんどの点が異なります。 Windows フォームのデザイン時アーキテクチャの詳細については、「デザイン時サポートの拡張」を参照してください。
ComponentModel フレームワークと WPF フレームワーク間の主な相違点
次の表に、WPF デザイナー アーキテクチャと System.ComponentModel フレームワークとの相違点を示します。
ComponentModel フレームワーク |
WPF デザイナー フレームワーク |
---|---|
IComponent インターフェイス、IContainer インターフェイス、および ISite インターフェイスによって異なる。 |
FrameworkElement クラスによって異なる。 |
ホストから渡されるデザイン時サービスに依存する。 |
デザイナーは宣言により最小限の要件を発行する。 |
各コントロール型に専用デザイナー型がある。 |
1 つのコントロール型で実行できる機能の数に制限なし。 |
各コントロール型に対してメタデータがハードコーディングされ、コントロールのコンパイル時に固定される。 |
メタデータは別のアセンブリで提供され、ツールによりカスタマイズまたは置換可能。 これにより、コントロールとは独立してデザイン時メタデータが更新される。 |
IDesignerHost がデザイナーの状態を保持する。 |
EditingContext クラスがデザイナーの状態を保持する。 |
サービスは IServiceContainer 実装で収集および共有される。 |
EditingContext クラスがサービス参照を保持する。 |
BehaviorService がキーボード、マウス、およびコマンドとの対話を管理する。 |
WPF デザイナー ツール アーキテクチャがキーボード、マウス、およびコマンドとの対話を管理する。 |
編集オブジェクト モデルは、PropertyDescriptor クラスを介した遅延バインディング アクセスを行うランタイム コントロールで構成される。 |
編集オブジェクト モデルはランタイム コントロールを抽象化する間接層を提供する。 カテゴリ エディターにより、1 つの UI 内の複数のプロパティを編集できる。 |
IComponent とFrameworkElement の比較
WPF 要素は、WPF コア サービスとフレームワーク レベル要素クラス間の接続を行う FrameworkElement クラスから派生します。
WPF 要素は IComponent インターフェイスを実装しません。 これが、WPF デザイナーが System.ComponentModel フレームワークを使用しない理由の 1 つです。 つまり、WPF コントロールが配置されることはありません。 したがって、WPF コントロールは System.ComponentModel デザイン環境からデザイナー サービスを要求できません。
デザイン時サービス
System.ComponentModel フレームワークのデザイナーは、デザイン環境からサービスを要求します。 WPF デザイナー フレームワークでは、サービスの環境を問い合わせることなく、ほとんどのタスクを実行できます。
System.ComponentModel フレームワークでは、デザイナー ホストにデザイン サービスが必ず存在している保証がないため、カスタム デザイナー コードは、GetService メソッドを呼び出した後に必ず null 参照をチェックする必要があります。 デザイナー コードは、サービスが存在していない場合、効率を低下させて機能を維持する必要がありますが、これは多くの場合うまくいきません。
WPF デザイナー フレームワークでは、カスタム デザイナーは最小限の要件のみ発行します。 ホストがコントラクトを満たすことができない場合、デザイナーは読み込みを行いません。 これにより、全体的な実装がシンプルになり、信頼性が高まります。
専用デザイナー型とメタデータの切り離し
System.ComponentModel フレームワークでは、デザイナー型は DesignerAttribute メタデータ属性を介して対応するコンポーネントに関連付けられます。 つまり、コンパイル時に構築される関係によって、コンポーネントの実行時動作とデザイン時動作間のハードコーディングされた依存性が決定されます。 別のデザイナーをアタッチするには、DesignerAttribute 宣言を変更し、コンポーネントのコード ベースを再コンパイルする必要があります。
WPF デザイナーでは、デザイナー メタデータは別のアセンブリに組み込まれ、実行時実装とは物理的に切り離されます。 この切り離しにより、ツールごとに、同じランタイム型に対しても完全に異なるデザイン環境を提供できます。 詳細については、「AttributeTable」を参照してください。
編集オブジェクト モデル
System.ComponentModel フレームワークでは、カスタム デザイナーは、PropertyDescriptor クラスを介して遅延バインディング方法でコントロールにアクセスします。 この規則は、デザイン環境によって強制的に適用されるわけではないため、PropertyDescriptor クラスを介してコントロールにアクセスする処理を開発者が忘れた場合、バグの原因になります。
WPF デザイナー フレームワークでは、カスタム デザイナーは、編集オブジェクト モデルを介してランタイム コントロールと対話します。 このモデルは、コントロールをモデルとビューに抽象化する間接層を提供します。 このオブジェクト モデルにより、PropertyDescriptor クラスを介してコントロールにアクセスする必要がなくなりました。
ComponentModel デザイナー フレームワークとの類似性
編集コンテキストは WPF デザイナーの基盤です。 EditingContext クラスが、デザイナーのコンテキスト状態を格納します。
編集コンテキストは、System.ComponentModel.Design 名前空間の IDesignerHost インターフェイスと概念的に類似しています。 IDesignerHost インターフェイスは、そのインターフェイスの多くの機能を定義しますが、EditingContext クラスはデータ機能と動作機能のみに集中しています。
編集コンテキストは、IServiceContainer インターフェイスと類似した方法でサービスを公開します。 編集コンテキストは列挙体をサポートしていますが、追加したサービスの削除はサポートしていません。 詳細については、「コンテキスト アーキテクチャの編集」を参照してください。
属性の使用方法における相違点
デザイナー属性は、WPF デザイナー アーキテクチャと Windows フォーム アーキテクチャでは意味が異なります。 次の表に、デザイナー関連属性の使用方法における 2 つのフレームワーク間での相違点を示します。
属性 |
Windows フォームの [プロパティ] ウィンドウ |
WPF デザイナーの [プロパティ] ウィンドウと Expression Blend のプロパティ インスペクター |
---|---|---|
プロパティが別のソースからその値を取得できるようにするために、プロパティに渡す値を指定します。 これは、アンビエンスと呼ばれます。 |
なし |
|
プロパティまたはイベントを [プロパティ] ウィンドウに表示するかどうかを指定します。 |
プロパティまたはイベントを [プロパティ] ウィンドウに表示するかどうかを指定します。 通常は表示されないプロパティを明示的に true に設定すると、そのプロパティが表示されます。 |
|
PropertyGrid コントロールが [項目別] モードに設定されているときに、コントロールに表示するプロパティまたはイベントを分類するカテゴリの名前を指定します。 |
[プロパティ] ウィンドウに表示するときに、プロパティをグループ化するためのカテゴリの名前を指定します。 |
|
プロパティの既定値を指定します。 |
CLR データ型に対して、プロパティの既定値を指定します。 依存関係プロパティでは無視されます。 |
|
プロパティまたはイベントの説明を指定します。 |
なし |
|
プロパティ、イベント、または、引数を受け取らないパブリックな void メソッドの表示名を指定します。 |
[プロパティ] ウィンドウに表示される、この属性が適用されるプロパティの名前を指定します。 |
|
プロパティの変更に使用するエディターを指定します。 |
プロパティの変更に使用するエディターを指定します。マルチ プロパティのカテゴリ エディターも含まれます。 |
|
なし |
EditorBrowsableState.Advanced は、カテゴリ エディターとプロパティを Advanced エキスパンダーに登録します。 |
|
クラスまたはメンバーのコンテキスト キーワードを指定します。 |
なし |
|
プロパティをローカライズするかどうかを指定します。 |
なし |
|
オブジェクトのテキスト表現が、アスタリスク (*) などの文字で隠されることを示します。 |
なし |
|
この属性がバインドされているプロパティをデザイン時に読み取り専用にするか、読み書き両用にするかを指定します。 |
この属性がバインドされているプロパティをデザイン時に読み取り専用にするか、読み書き両用にするかを指定します。 ReadOnlyAttribute でマークされたプロパティは、プロパティ インスペクターの文字列エディターに読み取り専用オブジェクトを表示します。 |
|
関連付けられているプロパティ値が変更されたときに [プロパティ] ウィンドウを更新することを示します。 |
なし |
|
この属性がバインドされているオブジェクトのコンバーターとして使用する型を指定します。 |
この属性がバインドされているオブジェクトのコンバーターとして使用する型を指定します。 |
|
コンポーネントの既定のイベントを指定します。 |
コンポーネントの既定のイベントを指定します。これにより、ダブルクリックで作成されるイベント ハンドラーが決まります。 |
|
コンポーネントの既定のプロパティを指定します。 |
コンポーネントの既定のプロパティを指定します。これにより、既定で選択されるプロパティが決まります。 |
|
コンポーネントのデザイン時のサービスの実装に使用するクラスを指定します。 |
なし |
|
クラスのデザイナーが特定のカテゴリに属すように指定します。 |
なし |
|
ツールボックス項目の属性を表します。 |
なし |
|
ツールボックスに使用するフィルター文字列とフィルターの種類を指定します。 |
なし |
|
なし |
ツールボックスに追加する型に対してアセンブリが検証される際、ツールボックスでの型表示を禁止します。 |
|
なし |
コレクション エディターまたはサブプロパティ エディターのコンボ ボックスに追加する項目を指定します。 作成をカスタマイズするファクトリを指定できます。 |
|
なし |
[プロパティ] ウィンドウでのプロパティの表示順序を指定します。 |
次の属性は、WPF デザイナー フレームワークでのみ使用され、Windows フォーム デザイナー フレームワークでは使用されません。
ツールボックス アイコンの指定方法の相違点
Windows フォーム デザイナーのフレームワークでは、カスタム コントロールに対してツールボックス アイコンを指定する場合、ToolboxBitmapAttribute をコントロール クラスに適用します。
WPF デザイナー フレームワークでは、埋め込みリソースと名前付け規則を使用して、ツールボックス ビットマップを指定します。 さらに、ToolboxBrowsableAttribute を使用して、ツールボックスの設定に使用できるアセンブリ内の型を制限します。
メタデータの指定方法の相違点
Windows フォームでは、デザイナー メタデータは、宣言で DesignerAttribute などの属性を使用して指定します。
WPF デザイナー アーキテクチャでは、デザイナー メタデータは AttributeTable で指定します。