德尔福:我如何知道我的属性编辑器正在编辑什么?
-
22-09-2019 - |
题
我有一个属性编辑器(TPropertyEditor 的后代),用于编辑属性。
当需要编辑我的属性时,我如何知道我正在编辑的对象的哪些属性?如果我要编辑一个属性,我必须知道我正在编辑什么属性。
我绞尽脑汁,翻遍了Delphi帮助、在线帮助、TPropertyEditor和后代源代码,但我找不到答案。
我期待这样的事情:
TPropertyEditor = class(...)
public
procedure Initialize(TheObject: TObject; ThePropertyName: string);
end;
据我所知,我的属性编辑器已创建,我将被告知“编辑”,我只需猜测他们希望我编辑哪些属性。
来自帮助:
编辑整个属性
您可以选择提供一个对话框,用户可以在其中视觉上编辑属性。属性编辑器最常见的用途是对本身就是类的属性。一个例子是 字体 属性,用户可以打开字体对话框,以一次选择字体的所有属性。
要提供一个整个专业编辑器对话框,请覆盖属性编辑班 编辑 方法。
编辑 方法使用以书面形式使用的相同的GET和设置方法 获取价值 和 设定值 方法。实际上,一个 编辑 方法将GET方法和设置方法称为。由于编辑器是特定于类型的,因此通常无需将属性值转换为字符串。编辑器通常处理“检索”的值。
当用户单击属性旁边的“ ...”按钮或双击值列时,对象检查器调用属性编辑器的 编辑方法。
在您的实施中 编辑 方法,请按以下步骤操作:
- 构建您用于属性的编辑器。
- 阅读当前值并使用GET方法分配给属性。
- 当用户选择一个新值时,请使用设定方法将该值分配给属性。
- 毁掉编辑器。
回答
它被隐藏起来,没有记录,但我发现了如何。我正在编辑的属性:
TheCurrentValue := TMyPropertyThing(Pointer(GetOrdValue));
现在我有了值,我可以编辑它了。如果我想用其他对象替换该属性:
SetOrdValue(Longint(TheNewValue));
完整代码:
创建一个继承自的属性编辑器 T类属性:
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;
接下来就是实际工作了。当用户单击“...”按钮时,对象检查器调用我的 编辑 方法。我缺少的技巧是我打电话给我的 获取订单值 方法。尽管我的财产不是 序数, ,你仍然使用它,只需将结果转换为一个对象:
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 方法,您的 Edit 函数可以使用它们来检索值。或者,如果它不是这些类型之一(例如,如果它是从 TPercient 派生的对象),那么您可以调用 GetOrdValue 并将结果转换为 TPercient。
另外,您可能需要查看 JVCL 的 JvDsgnEditors 单元中的 TJvPersistentPropertyEditor 以用作基类。它为您提供了一些功能。
顺便说一句,如果您确实需要它,可以使用 GetName 方法,该方法将为您提供属性的名称,但通常不必这样做。如果您继承自 TPropertyEditor 本身以外的其他内容,请小心,因为 GetName 是 虚拟的 并且可以被覆盖。
其他提示
属性编辑器将有关其正在编辑的对象和属性的信息保留为私有 FPropList
多变的。IDE 通过调用编辑器来填充该内容 SetPropEntry
方法。然后你通常应该调用以下的各种方法 TPropertyEditor
找出属性的值。
要求您编辑哪个属性并不重要。您的属性编辑器编辑特定类型的属性。对于就地编辑,您的编辑器提供了以下实现 SetValue
它将来自对象检查器的字符串转换为该属性的正确类型的值,然后调用适当的 Set
函数,例如 SetOrdValue
或者 SetIntfValue
. 。对于整个属性编辑,IDE 不会调用 SetValue
. 。相反,它会调用 Edit
, ,并且您应该致电 GetOrdValue
或者 GetIntfValue
(例如)您自己,因为您的编辑器已经知道它要编辑的属性类型。
请记住,属性编辑器通常可以同时编辑多个属性。这 姓名 所有这些属性的属性都是相同的,但它们所属的组件类型可能会有所不同,因此它们的 getter 和 setter 也可能会有所不同。致电您的房产编辑 GetName
方法找出名称。要获取对象,请调用 GetComponent
对于从 0 到的每个索引 PropCount
- 1.(当心;这些没有范围检查 Get
函数。)您还可以通过调用来检查特定对象是否在列表中 HasInstance
. 。这 GetPropInfo
方法会告诉你 PPropInfo
指针为 第一的 属性,但我认为它不一定等于所有其他属性的指针。除此之外,您无法直接访问 PPropInfo
数据,但同样,这真的不重要。如果您认为您的编辑需要这个,那么您就是 大概 做错事;发布一个新问题,其中包含有关您的基本任务的更具体信息。
房地产编辑只关心(并注册) 类型 的属性,而不是特定的属性本身。