Delphi 德尔菲:我如何知道我的属性编辑器正在编辑什么?

Delphi 德尔菲:我如何知道我的属性编辑器正在编辑什么?,delphi,propertyeditor,Delphi,Propertyeditor,我有一个属性编辑器(TPropertyEditor的后代),用于编辑属性 当需要编辑我的属性时,我如何知道我正在编辑的对象的属性?如果我要编辑一个属性,我必须知道我正在编辑什么属性 我一直在胡思乱想,筛选Delphi帮助、在线帮助、TPropertyEditor和后代源代码,但我找不到答案 我期望的是: TPropertyEditor = class(...) public procedure Initialize(TheObject: TObject; ThePropertyName:

我有一个属性编辑器(TPropertyEditor的后代),用于编辑属性

当需要编辑我的属性时,我如何知道我正在编辑的对象的属性?如果我要编辑一个属性,我必须知道我正在编辑什么属性

我一直在胡思乱想,筛选Delphi帮助、在线帮助、TPropertyEditor和后代源代码,但我找不到答案

我期望的是:

TPropertyEditor = class(...)
public
    procedure Initialize(TheObject: TObject; ThePropertyName: string);
end;
据我所知,我的属性编辑器已经创建,我将被告知“编辑”,我只需要预测他们希望我编辑的属性


从帮助中:

编辑整个属性

您可以选择提供一个对话框 用户可以在其中直观地看到 编辑属性。最常用 属性编辑器的作用是用于属性 这本身就是课堂。一 例如,字体属性 用户可以打开一个字体对话框 框以选择的所有属性 立即打开字体

提供 “整个属性编辑器”对话框, 重写属性编辑器类的 编辑方法

编辑方法使用相同的方法 获取和设置写作中使用的方法 GetValue和SetValue方法。在里面 事实上,Edit方法同时调用Get和 方法和集合方法。因为 编辑器是特定于类型的,有 通常不需要转换 属性值转换为字符串。编辑 通常将“作为”处理价值 找回。”

当用户单击“…”按钮时 属性旁边或双击 值列,对象检查器 调用属性编辑器的“编辑” 方法

在您的实施范围内 在“编辑”方法中,请执行以下步骤:

  • 构造您正在使用的编辑器 为了财产
  • 读电流 值并将其指定给属性 使用Get方法
  • 当用户 选择一个新值,然后指定该值 使用集合方法创建属性
  • 摧毁编辑
  • 答复 它被藏起来了,没有记录,但我发现了。我正在编辑的、我正在编辑的属性:

    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;
    
    接下来是实际工作。当用户单击“…”按钮时,对象检查器调用myEdit方法。我缺少的技巧是调用我的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;
    

    属性编辑器只关心(并注册)属性的类型,而不是特定属性本身。

    如果我没有弄错您的问题,您会想知道如何实际找到需要编辑的值,尤其是当所涉及的对象包含多个属性时。答案是IDE为您设置了它,并且在调用Edit时属性编辑器是“预加载”的。TPropertyEditor附带了一系列GetValue方法,您的编辑函数可以使用这些方法来检索值。或者,如果它不是这些类型之一(例如,如果它是从TPersistent派生的对象),则可以调用GetOrdValue并将结果强制转换为TPersistent

    此外,您可能希望在JVCL的JvDsgnEditors单元中签出TJvPersistentPropertyEditor以用作基类。它为您提供了一些功能


    顺便说一句,如果您真的需要它,您可以使用GetName方法,它将为您提供属性的名称,但您通常不必这样做。如果您继承的不是TPropertyEditor本身,请小心,因为GetName是虚拟的,可以被覆盖。

    属性编辑器将其正在编辑的对象和属性的信息保存在private
    FPropList
    变量中。IDE通过调用编辑器的
    SetPropEntry
    方法来填充该属性。然后通常需要调用的各种方法来查找属性的值

    你被要求编辑哪个属性并不重要。属性编辑器编辑特定类型的属性。对于就地编辑,编辑器提供了一个
    SetValue
    实现,该实现将对象检查器中的字符串转换为属性的适当类型的值,然后调用适当的
    Set
    函数,例如
    SetOrdValue
    SetIntfValue
    。对于整个属性编辑,IDE不会调用
    SetValue
    。相反,它将调用
    Edit
    ,您需要自己调用
    GetOrdValue
    GetIntfValue
    (例如),因为您的编辑器已经知道它要编辑的属性类型

    请记住,属性编辑器通常可以同时编辑多个属性。所有属性的名称都相同,但它们所属的组件类型可能不同,因此它们的getter和setter也可能不同。调用属性编辑器的
    GetName
    方法来查找名称。要获取对象,请为从0到PropCount的每个索引调用
    GetComponent
    。(小心;在那些
    Get
    函数中没有范围检查。)您还可以通过调用
    HasInstance
    来检查特定对象是否在列表中。
    GetPropInfo
    方法将告诉您第一个属性的
    PPropInfo
    指针,但我认为