我有一个属性编辑器(TPropertyEditor的后代),用于编辑属性。
当需要编辑我的属性时,我怎么知道我正在编辑什么对象的属性?如果我要编辑一个属性,我必须知道我正在编辑什么属性。
我一直在拉我的头发,筛选Delphi的帮助,在线帮助,以及TPropertyEditor和后代源代码,我找不到答案。
我期待的是:
TPropertyEditor = class(...)
public
procedure Initialize(TheObject: TObject; ThePropertyName: string);
end;
据我所知,我的属性编辑器已创建,我将被告知“编辑”,我只需要判断他们希望我编辑的属性。
来自帮助:
整体编辑属性
您可以选择提供对话框 用户可以在视觉上使用的框 编辑一个属性。最常见的用途 属性编辑器是属性 这本身就是课程。一个 示例是 Font 属性,用于 用户可以打开字体对话框 框选择的所有属性 一次性的字体。
提供一个 整个属性编辑器对话框, 覆盖属性编辑器类 编辑方法。
编辑方法使用相同的方法 获取和设置书面使用的方法 GetValue 和 SetValue 方法。在 事实上, Edit 方法同时调用Get 方法和Set方法。因为 编辑器是特定类型的,有 通常不需要转换 属性值到字符串。编辑 通常处理“as as”的值 检索“。
当用户点击“...”按钮时 在酒店旁边或双击 值列,Object Inspector 调用属性编辑器的编辑 方法。
在您的实施中 编辑方法,请按以下步骤操作:
- 构建您正在使用的编辑器 为了财产。
- 阅读当前内容 值并将其分配给属性 使用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;
接下来是实际工作。当用户单击“...”按钮时,对象检查器会调用我的编辑方法。我缺少的技巧是我调用 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;
答案 0 :(得分:4)
如果我理解你的问题,你会想知道你应该如何真正找到你需要编辑的值,特别是如果有问题的对象包含多个。答案是IDE为您设置了这个,并且在调用Edit时“属性编辑器”被“预加载”。 TPropertyEditor附带了一堆GetValue方法,Edit函数可以使用这些方法来检索值。或者,如果它不是这些类型中的一种,(例如,如果它是来自TPersistent的对象),那么您可以调用GetOrdValue并将结果转换为TPersistent。
此外,您可能希望检查JVCL的JvDsgnEditors单元中的TJvPersistentPropertyEditor以用作基类。它为您提供了一些功能。
顺便说一句,如果你真的需要它,你可以使用GetName方法,它将为你提供属性的名称,但你通常不应该这样做。如果你继承了TPropertyEditor以外的东西,请小心,因为GetName是虚拟并且可以被覆盖。
答案 1 :(得分:3)
属性编辑器在私有FPropList
变量中保存有关正在编辑的对象和属性的信息。 IDE通过调用编辑器的SetPropEntry
方法填充该内容。然后,您通常应该调用TPropertyEditor
的各种方法来查找属性的值。
要求编辑哪个属性并不重要。您的属性编辑器编辑特定类型的属性。对于就地编辑,编辑器提供了SetValue
的实现,它将Object Inspector中的字符串转换为属性的正确类型的值,然后调用相应的Set
函数,例如为SetOrdValue
或SetIntfValue
。对于整个属性编辑,IDE不会调用SetValue
。相反,它会调用Edit
,您需要自己调用GetOrdValue
或GetIntfValue
(例如),因为您的编辑已经知道它要编辑的属性类型。< / p>
请记住,属性编辑器通常可以同时编辑多个属性。属性的名称对于所有属性都是相同的,但它们所属的组件类型可能会有所不同,因此它们的getter和setter也是如此。请致电您的媒体编辑器的 GetName
方法,找出该名称。要获取对象,请为从0到GetComponent
的每个索引调用 PropCount
- 1.(注意;这些Get
函数中没有范围检查。)您还可以通过调用HasInstance
来检查列表中是否有特定对象。 GetPropInfo
方法将告诉您 first 属性的PPropInfo
指针,但我认为这不一定等于所有其他属性的指针。除此之外,您无法直接访问PPropInfo
数据,但同样,它确实无关紧要。如果您认为编辑需要它,那么可能做错了事;发布一个新问题,其中包含有关基础任务的更具体信息。
答案 2 :(得分:2)
属性编辑只关心(并注册)属性的类型,而不关心特定属性本身。