プロパティの編集に使用されるプロパティ エディタ (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メソッドの実装内で、次の手順に従います。
- プロパティに使用しているエディターを構築します。
- 現在の値を読み取り、Get メソッドを使用してプロパティに割り当てます。
- ユーザーが新しい値を選択したら、Set メソッドを使用してその値をプロパティに割り当てます。
- エディターを破棄します。
答え
それは隠れていて、文書化されていませんが、その方法を見つけました。私が編集している編集中のプロパティ:
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;