delphipropertyeditor

Delphi: How do i know what my property editor is editing?


i have a property editor (descendant of TPropertyEditor) that is used to edit a property.

When it comes time to edit my property, how do i know what property of what object i'm editing? If i'm going to edit a property, i have to know what property i'm editing.

i've been pulling my hair out, sifting through the Delphi help, the online help, and the TPropertyEditor and descendant source code, and i can't find the answer.

i expected something like:

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

As far as i can tell, my property editor is created, and i will be told to "Edit", and i just have to divine what property they wanted me to edit.


From the help:

Editing the property as a whole

You can optionally provide a dialog box in which the user can visually edit a property. The most common use of property editors is for properties that are themselves classes. An example is the Font property, for which the user can open a font dialog box to choose all the attributes of the font at once.

To provide a whole-property editor dialog box, override the property-editor class’s Edit method.

Edit methods use the same Get and Set methods used in writing GetValue and SetValue methods. In fact, an Edit method calls both a Get method and a Set method. Because the editor is type-specific, there is usually no need to convert the property values to strings. The editor generally deals with the value “as retrieved.”

When the user clicks the ‘...’ button next to the property or double-clicks the value column, the Object Inspector calls the property editor’s Edit method.

Within your implementation of the Edit method, follow these steps:

  1. Construct the editor you are using for the property.
  2. Read the current value and assign it to the property using a Get method.
  3. When the user selects a new value, assign that value to the property using a Set method.
  4. Destroy the editor.

Answer

It's tucked away, and not documented, but i found out how. The property i'm editing that i edit:

TheCurrentValue := TMyPropertyThing(Pointer(GetOrdValue));

Now that i have the value, i can edit it. If i want to replace the property with some other object:

SetOrdValue(Longint(TheNewValue));

The full code:

Create a property editor that descends from TClassProperty:

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

First is the housekeeping, telling Delphi's object inspector that my property editor will display a dialog box, this will make a "..." appear next to the property:

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

Next is the actual work. When the user clicks the "..." button, the object inspector calls my Edit method. The trick that i was missing is that i call my GetOrdValue method. Even though my property isn't an ordinal, you still use it, and just cast the resulting thing to an object:

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;

Solution

  • If I understand your question right, you're wondering how you're supposed to actually find the value you need to be editing, especially if the object in question contains more than one of them. The answer is that the IDE sets that up for you and the property editor comes "preloaded" by the time Edit is called. TPropertyEditor comes with a bunch of GetValue methods that your Edit function can use to retrieve the value. Or if it's not one of those types, (if it's an object descended from TPersistent, for example,) then you can call GetOrdValue and cast the result to a TPersistent.

    Also, you might want to check out TJvPersistentPropertyEditor in the JvDsgnEditors unit of the JVCL to use as a base class. It provides some of the functionality for you.

    BTW if you really need it, you can use the GetName method, which will give you the name of the property, but you usually shouldn't have to. And be careful if you're inheriting from something other than TPropertyEditor itself, as GetName is virtual and can be overridden.