2

プロパティの編集に使用されるプロパティ エディタ (TPropertyEditor の子孫) があります。

自分のプロパティを編集するときが来たら、どのオブジェクトのどのプロパティを編集しているかを知るにはどうすればよいですか? プロパティを編集する場合、編集しているプロパティを知る必要があります。

Delphi ヘルプ、オンライン ヘルプ、TPropertyEditor と子孫のソース コードを調べてみましたが、答えが見つかりません。

私は次のようなものを期待していました:

TPropertyEditor = class(...)
public
    procedure Initialize(TheObject: TObject; ThePropertyName: string);
end;

私が知る限り、プロパティ エディターが作成され、「編集」するように言われます。どのプロパティを編集してほしいかを推測する必要があります。


ヘルプから:

プロパティ全体の編集

オプションで、ユーザーがプロパティを視覚的に編集できるダイアログ ボックスを提供できます。プロパティ エディタの最も一般的な用途は、それ自体がクラスであるプロパティです。たとえば、Fontプロパティでは、ユーザーはフォント ダイアログ ボックスを開いて、フォントのすべての属性を一度に選択できます。

プロパティ エディタ ダイアログ ボックス全体を提供するには、プロパティ エディタ クラスの Editメソッドをオーバーライドします。

Editメソッドは、 GetValueおよびSetValueメソッドを記述する際に使用されるのと同じ Get および Set メソッドを使用し ます。実際、Editメソッドは Get メソッドと Set メソッドの両方を呼び出します。エディターはタイプ固有であるため、通常、プロパティ値を文字列に変換する必要はありません。通常、エディターは「取得したまま」の値を扱います。</p>

ユーザーがプロパティの横にある [...] ボタンをクリックするか、値列をダブルクリックすると、オブジェクト インスペクタはプロパティ エディタのEdit メソッドを呼び出します。

Editメソッドの実装内で、次の手順に従います。

  1. プロパティに使用しているエディターを構築します。
  2. 現在の値を読み取り、Get メソッドを使用してプロパティに割り当てます。
  3. ユーザーが新しい値を選択したら、Set メソッドを使用してその値をプロパティに割り当てます。
  4. エディターを破棄します。

答え

それは隠れていて、文書化されていませんが、その方法を見つけました。私が編集している編集中のプロパティ:

TheCurrentValue := TMyPropertyThing(Pointer(GetOrdValue));

値を取得したので、編集できます。プロパティを他のオブジェクトに置き換えたい場合:

SetOrdValue(Longint(TheNewValue));

完全なコード:

TClassPropertyから派生するプロパティ エディタを作成します。

TMyPropertyEditor = class(TClassProperty)
public
   procedure Edit; override;
   function GetAttributes: TPropertyAttributes; override;
end;

最初はハウスキーピングです。Delphi のオブジェクト インスペクタに、プロパティ エディタにダイアログ ボックスが表示されることを伝えます。これにより、プロパティの横に「...」が表示されます。

function TMyPropertyEditor.GetAttributes: TPropertyAttributes;
begin
   //We show a dialog, make Object Inspector show "..."
   Result := [paDialog];
end;

次は実際の作業です。ユーザーが「...」ボタンをクリックすると、オブジェクト インスペクターがEditメソッドを呼び出します。私が見逃していたトリックは、GetOrdValueメソッドを呼び出すことです。私のプロパティは序数ではありませんが、それでもそれを使用し、結果をオブジェクトにキャストするだけです:

procedure TMyPropertyEditor.Edit;
var
   OldThing: TMyPersistentThing;
   NewThing: TMyPersistentThing;
begin
   //Call the property's getter, and return the "object" i'm editing:
   OldThing:= TMyPersistentThing(Pointer(GetOrdValue));

   //now that i have the thing i'm editing, do stuff to "edit" it
   DoSomeEditing(OldThing);


   //i don't have to, but if i want to replace the property with a new object
   //i can call the setter:
   NewThing := SomeVariant(OldThing);
   SetOrdValue(Longint(NewThing));
end;
4

3 に答える 3

4

私があなたの質問を正しく理解していれば、特に問題のオブジェクトに複数の値が含まれている場合、編集する必要がある値を実際にどのように見つけるべきか疑問に思っているでしょう。答えは、IDE が自動的に設定し、Edit が呼び出されるまでにプロパティ エディタが「プリロード」されるということです。TPropertyEditor には、Edit 関数で値を取得するために使用できる一連の GetValue メソッドが付属しています。または、これらのタイプのいずれでもない場合 (たとえば、TPersistent から派生したオブジェクトの場合)、GetOrdValue を呼び出して、結果を TPersistent にキャストできます。

また、JVCL の JvDsgnEditors ユニットにある TJvPersistentPropertyEditor を確認して、基本クラスとして使用することもできます。いくつかの機能を提供します。

ところで、本当に必要な場合は、プロパティの名前を取得する GetName メソッドを使用できますが、通常はそうする必要はありません。また、TPropertyEditor 以外のものから継承する場合は注意してください。GetName は仮想であり、オーバーライドできるからです。

于 2010-01-04T05:28:49.243 に答える
3

プロパティ エディターは、編集中のオブジェクトとプロパティに関する情報をプライベートFPropList変数に保持します。SetPropEntryIDE は、エディタのメソッドを呼び出すことで、これを埋めます。次に、通常TPropertyEditor、プロパティの値を見つけるために のさまざまなメソッドを呼び出すことになっています。

どのプロパティを編集するように求められたかは問題ではありません。プロパティ エディタは、特定のタイプのプロパティを編集します。インプレース編集の場合、エディターはSetValue、オブジェクト インスペクターからの文字列をプロパティの適切な型の値に変換する の実装を提供します。その後、またはSetなどの適切な関数を呼び出します。プロパティ全体の編集の場合、IDE は を呼び出しません。代わりに、それは を呼び出します。編集者は、編集するように設計されたプロパティのタイプを既に知っているため、(たとえば) 自分自身をorに呼び出すことが期待されます。SetOrdValueSetIntfValueSetValueEditGetOrdValueGetIntfValue

通常、プロパティ エディタは複数のプロパティを同時に編集できることに注意してください。プロパティの名前はそれらすべてで同じになりますが、それらが属するコンポーネントのタイプは異なる場合があり、そのためゲッターとセッターも異なります。プロパティ エディタのGetNameメソッドを呼び出して、名前を見つけます。オブジェクトを取得するには、GetComponent0 から -1 までの各インデックスを呼び出しPropCountます (注意してください。これらの関数では範囲チェックは行われませんGet)。特定のオブジェクトがリストにあるかどうかは、 を呼び出して確認することもできますHasInstanceGetPropInfoメソッドは最初のプロパティのPPropInfoポインタを教えてくれますが、それが必ずしも他のすべてのプロパティのポインタと同じになるとは思いません。それを除けば、あなたはに直接アクセスすることはできませんPPropInfoデータですが、繰り返しますが、実際には問題ではありません。エディターにそれが必要だと思う場合は、おそらく何か間違ったことをしているでしょう。基礎となるタスクに関するより具体的な情報を含む新しい質問を投稿してください。

于 2010-01-04T06:18:32.153 に答える
2

プロパティ エディターは、特定のプロパティ自体ではなく、プロパティのタイプのみを考慮 (および登録) します。

于 2010-01-04T04:03:28.760 に答える