Delphi :我怎么知道我的属性编辑器正在编辑什么?

9gm1akwq  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(85)

我有一个属性编辑器(TPropertyEditor的后代),用于编辑属性。
当需要编辑属性时,我如何知道我正在编辑的是什么对象的什么属性?如果我要编辑一个属性,我必须知道我正在编辑的是什么属性。
我一直在绞尽脑汁,在 Delphi 帮助、在线帮助、TPropertyEditor和后代源代码中筛选,但我找不到答案。
我期待着这样的东西:

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

字符串
据我所知,我的属性编辑器被创建,我将被告知“编辑”,我只需要猜测他们想让我编辑什么属性。
从帮助:

编辑整个属性

您可以选择提供一个对话框,用户可以在其中直观地编辑属性。属性编辑器最常见的用途是用于本身就是类的属性。例如,Font 属性,用户可以打开一个字体对话框,一次选择字体的所有属性。
若要提供完整属性编辑器对话框,请重写属性编辑器类的 Edit 方法。

  • Edit* 方法使用与编写 GetValueSetValue 方法相同的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;

tzcvj98z

tzcvj98z1#

如果我理解你的问题是正确的,你想知道你应该如何找到你需要编辑的值,特别是当对象包含多个属性时。答案是IDE会为您设置属性编辑器,并且属性编辑器会“预加载”TPropertyEditor附带了一堆GetValue方法,您的Edit函数可以使用这些方法来检索值。或者,如果它不是这些类型之一,(例如,如果它是从TPersistent继承而来的对象),那么您可以调用GetOrdValue并将结果强制转换为TPersistent
此外,您可能希望在JVCL的JvDsgnEditors单元中检查TJvPersistentPropertyEditor以用作基类。它为您提供了一些功能。
顺便说一句,如果你真的需要它,你可以使用GetName方法,它会给你给予属性的名称,但你通常不应该这样做。如果你继承的是TPropertyEditor本身以外的东西,要小心,因为GetName是**virtual**,可以被重写。

ulydmbyx

ulydmbyx2#

属性编辑器在私有变量FPropList中保存有关正在编辑的对象和属性的信息。IDE通过调用编辑器的SetPropEntry方法来填充该信息。然后通常应该调用TPropertyEditor的各种方法来查找属性的值。
您被要求编辑哪个属性并不重要。您的属性编辑器编辑特定类型的属性。对于就地编辑,您的编辑器提供SetValue的实现,该实现将来自对象检查器的字符串转换为属性的正确类型的值,然后您调用适当的Set函数,例如SetOrdValueSetIntfValue。对于整个属性编辑,IDE不会调用SetValue。相反,它将调用Edit,并且您应该自己调用GetOrdValueGetIntfValue(例如),因为您的编辑器已经知道它要编辑的属性类型。
请记住,属性编辑器通常可以同时编辑多个属性。属性的 name 对于所有属性都是相同的,但是它们所属的组件类型可能不同,因此它们的getter和setter也可能不同。调用属性编辑器的**GetName方法来找出名称。要获取对象,对于从0到PropCount- 1的每个索引,调用GetComponent**。(小心;在这些Get函数中没有范围检查。您还可以通过调用HasInstance来检查特定对象是否在列表中。GetPropInfo方法将告诉您 firstPPropInfo指针。属性,但我不认为它一定等于所有其他属性的指针。除此之外,你不能直接访问PPropInfo数据,但同样,这真的不重要。如果你认为你的编辑器需要它,你可能做错了什么;发布一个新的问题,提供关于你的底层任务的更具体的信息。

4nkexdtk

4nkexdtk3#

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

相关问题