我有一个属性编辑器(TPropertyEditor的后代),用于编辑属性。
当需要编辑属性时,我如何知道我正在编辑的是什么对象的什么属性?如果我要编辑一个属性,我必须知道我正在编辑的是什么属性。
我一直在绞尽脑汁,在 Delphi 帮助、在线帮助、TPropertyEditor和后代源代码中筛选,但我找不到答案。
我期待着这样的东西:
TPropertyEditor = class(...)
public
procedure Initialize(TheObject: TObject; ThePropertyName: string);
end;
字符串
据我所知,我的属性编辑器被创建,我将被告知“编辑”,我只需要猜测他们想让我编辑什么属性。
从帮助:
编辑整个属性
您可以选择提供一个对话框,用户可以在其中直观地编辑属性。属性编辑器最常见的用途是用于本身就是类的属性。例如,Font 属性,用户可以打开一个字体对话框,一次选择字体的所有属性。
若要提供完整属性编辑器对话框,请重写属性编辑器类的 Edit 方法。
- Edit* 方法使用与编写 GetValue 和 SetValue 方法相同的Get和Set方法。事实上,Edit 方法调用Get方法和Set方法。由于编辑器是特定于类型的,因此通常不需要将属性值转换为字符串。编辑器通常处理“检索到的”值。
当用户单击属性旁边的“...”按钮或双击值列时,对象检查器将调用属性编辑器的 Edit 方法。
在 Edit 方法的实现中,请执行以下步骤:
1.构造用于属性的编辑器。
1.读取当前值并使用Get方法将其赋给属性。
1.当用户选择新值时,使用Set方法将该值赋给属性。
1.毁了编辑。
回复
它被隐藏起来,没有记录,但我发现了如何。我编辑的属性:
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方法。即使我的属性不是 ordinal,你仍然使用它,只是将结果转换为对象:
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;
型
3条答案
按热度按时间tzcvj98z1#
如果我理解你的问题是正确的,你想知道你应该如何找到你需要编辑的值,特别是当对象包含多个属性时。答案是IDE会为您设置属性编辑器,并且属性编辑器会“预加载”
TPropertyEditor
附带了一堆GetValue
方法,您的Edit
函数可以使用这些方法来检索值。或者,如果它不是这些类型之一,(例如,如果它是从TPersistent
继承而来的对象),那么您可以调用GetOrdValue
并将结果强制转换为TPersistent
。此外,您可能希望在JVCL的
JvDsgnEditors
单元中检查TJvPersistentPropertyEditor
以用作基类。它为您提供了一些功能。顺便说一句,如果你真的需要它,你可以使用
GetName
方法,它会给你给予属性的名称,但你通常不应该这样做。如果你继承的是TPropertyEditor
本身以外的东西,要小心,因为GetName
是**virtual
**,可以被重写。ulydmbyx2#
属性编辑器在私有变量
FPropList
中保存有关正在编辑的对象和属性的信息。IDE通过调用编辑器的SetPropEntry
方法来填充该信息。然后通常应该调用TPropertyEditor
的各种方法来查找属性的值。您被要求编辑哪个属性并不重要。您的属性编辑器编辑特定类型的属性。对于就地编辑,您的编辑器提供
SetValue
的实现,该实现将来自对象检查器的字符串转换为属性的正确类型的值,然后您调用适当的Set
函数,例如SetOrdValue
或SetIntfValue
。对于整个属性编辑,IDE不会调用SetValue
。相反,它将调用Edit
,并且您应该自己调用GetOrdValue
或GetIntfValue
(例如),因为您的编辑器已经知道它要编辑的属性类型。请记住,属性编辑器通常可以同时编辑多个属性。属性的 name 对于所有属性都是相同的,但是它们所属的组件类型可能不同,因此它们的getter和setter也可能不同。调用属性编辑器的**
GetName
方法来找出名称。要获取对象,对于从0到PropCount
- 1的每个索引,调用GetComponent
**。(小心;在这些Get
函数中没有范围检查。您还可以通过调用HasInstance
来检查特定对象是否在列表中。GetPropInfo
方法将告诉您 first 的PPropInfo
指针。属性,但我不认为它一定等于所有其他属性的指针。除此之外,你不能直接访问PPropInfo
数据,但同样,这真的不重要。如果你认为你的编辑器需要它,你可能做错了什么;发布一个新的问题,提供关于你的底层任务的更具体的信息。4nkexdtk3#
属性编辑器只关心(并注册)属性的类型,而不是特定的属性本身。