PLF のバージョン 2.0 では、埋め込みエディタと呼ばれる、非常に強力で柔軟な拡張メカニズムが導入されています。
埋め込みエディタは、データ値を描画し、場合によっては編集するために、別のコンポーネントの UIElement 内部に埋め込むことのできるオブジェクトです。埋め込みエディタの主な機能や概念について、次にまとめて説明します。
エディタ - 抽象基本クラス EmbeddableEditorBase から派生したクラス。エディタは、別のコンポーネントの UIElement 内部から値を描画または編集するために使用します。
エディタ オーナー - EmbeddableEditorOwnerBase から派生したクラスで、表示する値に関する情報をエディタに提供します。PLF ベースのコントロールはこの基本クラスからクラスを派生します。
エディタ コントロール - スタンドアロンの編集コントロールで、エディタと EmbeddableEditorOwnerBase 派生クラスを使用します。エディタ コントロールは、IProvidesEmbeddableEditor と呼ばれるインタフェースをオプションで実装することもでき、特定のデータ型の編集をサポートできるエディタのドロップダウン リストを移植するために、いくつかのカスタムの TypeConverter によって使用されます。たとえば、UltraGridColumn は EditorControl と呼ばれるプロパティを公開しています。このプロパティは、デザインタイムにフォーム上に置かれた IProvidesEmbeddableEditor を実装しているコントロールを反復して探し出す TypeConverter を持っています。これらのコントロールを使用して、プロパティ ブラウザのドロップダウン リストを移植します。IProvidesEmbeddableEditor インタフェースには、「Editor」という単一の読み取り専用プロパティがあります。このプロパティは EmbeddableEditorBase 派生クラスのインスタンスを返します。このエディタは、エディタの機能を決定する 2 つのメソッド、CanRenderType と CanEditType を公開しています。
埋め込みエレメント - EmbeddableUIElementBase 抽象クラスから派生した要素。エディタはこれらのクラスを定義および実装します。エレメントのインスタンスは、エディタの GetEmbeddableElement メソッドを呼び出すことで作成され、返されます。通常、このメソッドは親エレメント(たとえば、グリッドのセル エレメント)の PositionChildElements メソッド内部から呼び出されます。
オーナー コンテキスト - エディタ オーナーに対してのみ意味を持つオブジェクト。つまり、エディタからは完全に隠されたオブジェクトです。オーナー コンテキストは GetEmbeddableElement 呼び出しの中で渡され、埋め込みエレメントによって識別子またはクッキーとしてキャッシュされます。 キャッシュされたオーナー コンテキストは、編集または表示する値についての情報を取得するために後で EmbeddableEditorOwnerBase のメソッドを呼び出すときに使用されます。
編集モード - エディタが特定の値を編集しているときの状態。注:ひとつのエディタを使用して複数の値(グリッドのひとつ以上の列内にあるすべてのセルなど)を表示することもできますが、一度に編集できる値はひとつだけです。エディタは編集モードを開始または終了するためのメソッドとして EnterEditMode および ExitEditMode を公開しています。また、BeforeEnterEditMode(キャンセル可能)、AfterEnterEditMode、BeforeExitEditMode(キャンセル可能)、AfterExitEditMode の、4 つのイベントを提供しています。エディタは一度にひとつの値しか編集できないため、あるセルを編集中に別のセルで EnterEditMode メソッドを呼び出した場合、エディタは先に編集モードを終了します。
UltraGrid が埋め込み可能エディタを利用してセル データを描画する仕組みを次に示します。
UIElement の作成または配置が必要になる描画操作時(つまり、最初の描画時、または要素がダーティとしてマークされるような状態の変化が起こった後)に、ひとつ以上の CellUIElement の PositionChildElements メソッドが呼び出されます。このメソッドの中で、セル エレメントは自身に関連付けられている列に対して、使用すべき適切なエディタを問い合わせます。注:アプリケーション開発者は、列の Editor または EditorControl のどちらかのプロパティを設定して、どのエディタを使用すべきかを指定できます。エディタが指定されていなければ、列のデータ型に基づいて列からデフォルトのエディタが返されます。
セル エレメントはエディタの GetEmbeddableElement メソッドを呼び出します。その際、親エレメントとしてエレメント自体、オーナーとして列の EmbeddableEditorOwnerBase 派生インスタンス、オーナー コンテキストとしてエレメント自体をそれぞれ渡します。注:オーナー コンテキストには、オーナーが後でこの特定のセルを識別できるものであれば何を指定しても構いません。この仕組みは、同じエディタを使用してこの列(おそらく他の列も同様)の中にあるすべてのセルを表示するために必要となります。
前の手順の呼び出しで返された EmbeddableUIElementBase 派生インスタンスは、 エディタ、オーナー、およびオーナー コンテキストをキャッシュすると共に、GetEmbeddableElement メソッドに渡されたいくつかの追加のフラグもキャッシュします。続いてセルはこのエレメントのサイズをその境界線の内部に収まるように設定し、エレメントを ChildElements コレクションに追加します。
これ以降、セルのデータを描画するときに、エレメントは上の手順でキャッシュされた EmbeddableEditorOwnerBase 派生インスタンスの各種メソッドを呼び出し、必要な情報(セルのデータ値や外観など)を取得します。オーナーの各メソッドは、上記の手順で埋め込みエレメントにより同様にキャッシュされたオーナー コンテキストをパラメータとして受け取ります。そのため、オーナーは描画すべき特定のセルを識別できます。
UltraGrid が埋め込みエディタを利用してセル データを編集する仕組みを次に示します。
ユーザーがセルで何らかの操作(セルをクリックする、[F2] キーを押すなど)を実行して編集モードを開始します。
これにより、エディタの EnterEditMode が呼び出されます。このメソッドは EmbeddableUIElementBase 派生クラスのインスタンスをパラメータとして取得します。このインスタンスは、以前に特定のセルに対するエディタの GetEmbeddableElement メソッド(前述の描画ロジックの手順 2)から返されたものです。注:UIElement であるため、その四角形にはコントロールのクライアント座標が設定されています。
エディタは BeforeEnterEditMode イベントを発生し、このイベントをグリッドがリスニングします。イベントを受信したグリッドは、固有の BeforeEnterEditMode イベントを発生します。イベントの中で Cancel プロパティが True に設定されている場合は、以降の手順が省略され、エディタは編集モードになりません。
エディタは値の編集に必要な操作を実行します。たとえば、テキストボックスをエレメントの一部分の上に配置し、そのテキストにセルの値を設定したりします。
エディタは AfterEnterEditMode イベントを発生し、このイベントをグリッドがリスニングします。イベントを受信したグリッドは、固有の AfterEnterEditMode イベントを発生します。
これで、ユーザーは編集モードに入り、エディタが提供する UI に基づいてセルの値を編集できるようになります。
ユーザーが何らかの操作(別のセルをアクティブにする、[F2] キーや [Esc] キーを押すなど)を実行して編集モードを終了します。
これにより、エディタの ExitEditMode が呼び出されます。
エディタに(コンボボックスのような)ドロップダウン部分があり、それがドロップダウンしている場合、エディタはその CloseUp メソッドを呼び出して最初にそれを閉じます。注:これにより AfterCloseUp イベントが起動されます。
エディタは BeforeExitEditMode イベントを発生し、このイベントをグリッドがリスニングします。イベントを受信したグリッドは、固有の BeforeExitEditMode イベントを発行します。イベントの中で Cancel プロパティが True に設定されている場合、エディタは編集モードのままかわりません。True に設定されていなければ、グリッドは編集された値に基づいてセルの値を更新し、エディタは必要な後処理(テキストボックスの非表示など)を実行します。
エディタは AfterExitEditMode イベントを発生し、このイベントをグリッドがリスニングします。イベントを受信したグリッドは、固有の AfterExitEditMode イベントを発生します。
PLF に組み込まれているエディタのセットをスタンドアロンの編集コントロールなどの他のコントロールに密接に統合することができます。
特殊な編集のニーズに対応するためにカスタム エディタを開発できます。
コントロールは、グリッドの列と切り離されたプロパティを公開できるため、ユーザーはデザインタイムおよびランタイムにエディタを容易に置き換えることができます。