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

时间:2010-01-04 03:36:02

标签: delphi propertyeditor

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

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

我一直在拉我的头发,筛选Delphi的帮助,在线帮助,以及TPropertyEditor和后代源代码,我找不到答案。

我期待的是:

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

据我所知,我的属性编辑器已创建,我将被告知“编辑”,我只需要判断他们希望我编辑的属性。


来自帮助:

  

整体编辑属性

     

您可以选择提供对话框   用户可以在视觉上使用的框   编辑一个属性。最常见的用途   属性编辑器是属性   这本身就是课程。一个   示例是 Font 属性,用于   用户可以打开字体对话框   框选择的所有属性   一次性的字体。

     

提供一个   整个属性编辑器对话框,   覆盖属性编辑器类   编辑方法。

     

编辑方法使用相同的方法   获取和设置书面使用的方法    GetValue SetValue 方法。在   事实上, Edit 方法同时调用Get   方法和Set方法。因为   编辑器是特定类型的,有   通常不需要转换   属性值到字符串。编辑   通常处理“as as”的值   检索“。

     

当用户点击“...”按钮时   在酒店旁边或双击   值列,Object Inspector   调用属性编辑器的编辑   方法。

     

在您的实施中   编辑方法,请按以下步骤操作:

     
      
  1. 构建您正在使用的编辑器   为了财产。
  2.   
  3. 阅读当前内容   值并将其分配给属性   使用Get方法。
  4.   
  5. 当用户   选择一个新值,分配该值   使用Set方法到属性。
  6.   
  7. 销毁编辑器。
  8.   

答案

它隐藏起来,没有记录,但我发现了如何。我编辑的属性我编辑:

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;

3 个答案:

答案 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函数,例如为SetOrdValueSetIntfValue。对于整个属性编辑,IDE不会调用SetValue。相反,它会调用Edit,您需要自己调用GetOrdValueGetIntfValue(例如),因为您的编辑已经知道它要编辑的属性类型。< / p>

请记住,属性编辑器通常可以同时编辑多个属性。属性的名称对于所有属性都是相同的,但它们所属的组件类型可能会有所不同,因此它们的getter和setter也是如此。请致电您的媒体编辑器的 GetName 方法,找出该名称。要获取对象,请为从0到GetComponent的每个索引调用 PropCount - 1.(注意;这些Get函数中没有范围检查。)您还可以通过调用HasInstance来检查列表中是否有特定对象。 GetPropInfo方法将告诉您 first 属性的PPropInfo指针,但我认为这不一定等于所有其他属性的指针。除此之外,您无法直接访问PPropInfo数据,但同样,它确实无关紧要。如果您认为编辑需要它,那么可能做错了事;发布一个新问题,其中包含有关基础任务的更具体信息。

答案 2 :(得分:2)

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