【问题标题】:Delphi: How do i know what my property editor is editing?Delphi:我怎么知道我的属性编辑器正在编辑什么?
【发布时间】:2011-01-01 03:04:42
【问题描述】:

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

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

我一直在摸索,筛选 Delphi 帮助、在线帮助以及 TPropertyEditor 和后代源代码,但找不到答案。

我希望是这样的:

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

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


来自帮助:

整体编辑属性

您可以选择提供一个对话框 用户可以在其中直观地看到的框 编辑属性。最常见的用途 of 属性编辑器用于属性 它们本身就是类。一个 例如 Font 属性,例如 用户可以打开一个字体对话框 框选择所有属性 字体。

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

Edit 方法使用相同的 写作中使用的 Get 和 Set 方法 GetValueSetValue 方法。在 事实上,Edit 方法同时调用 Get 方法和 Set 方法。因为 编辑器是特定于类型的,有 通常不需要转换 属性值到字符串。编辑 通常处理值“as 已取回。”

当用户点击“...”按钮时 在属性旁边或双击 值列,对象检查器 调用属性编辑器的 Edit 方法。

在您实施 Edit 方法,请按以下步骤操作:

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

回答

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

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;

【问题讨论】:

    标签: delphi propertyeditor


    【解决方案1】:

    属性编辑器将有关其正在编辑的对象和属性的信息保存在私有FPropList 变量中。 IDE 通过调用编辑器的 SetPropEntry 方法来填充它。然后通常应该调用TPropertyEditor 的各种方法来找出属性的值。

    要求您编辑哪个属性并不重要。您的属性编辑器编辑特定类型的属性。对于就地编辑,您的编辑器提供了SetValue 的实现,它将来自对象检查器的字符串转换为属性的正确类型的值,然后调用适当的Set 函数,例如SetOrdValueSetIntfValue。对于整体属性编辑,IDE 不会调用 SetValue。相反,它会调用Edit,而您应该自己调用GetOrdValueGetIntfValue(例如),因为您的编辑器已经知道它要编辑的属性类型。

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

    【讨论】:

      【解决方案2】:

      如果我理解你的问题,你想知道你应该如何实际找到你需要编辑的值,特别是如果有问题的对象包含多个值。答案是 IDE 会为您设置好,并且在调用 Edit 时属性编辑器会“预加载”。 TPropertyEditor 带有一堆 GetValue 方法,您的 Edit 函数可以使用这些方法来检索值。或者,如果它不是这些类型之一(例如,如果它是从 TPersistent 派生的对象),那么您可以调用 GetOrdValue 并将结果转换为 TPersistent。

      此外,您可能需要检查 JVCL 的 JvDsgnEditors 单元中的 TJvPersistentPropertyEditor 以用作基类。它为您提供了一些功能。

      顺便说一句,如果你真的需要它,你可以使用 GetName 方法,它会给你属性的名称,但你通常不应该这样做。如果您从 TPropertyEditor 本身以外的其他东西继承,请小心,因为 GetName 是virtual并且可以被覆盖。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 这个示例代码有帮助吗? delphi3000.com/articles/article_829.asp?SK=
        • 沃伦,没关系,但不太对。属性编辑器不应直接修改属性(如通过分配Hint)。编辑器应该分配它自己的Value 属性,然后编辑器的基类将负责将新值传播到所有正在编辑的属性,而不仅仅是第一个对象的Hint 属性。多行字符串属性编辑器通常很有用;无需将其硬编码为仅在 Hint 属性上工作。
        猜你喜欢
        • 2020-05-19
        • 1970-01-01
        • 2019-09-05
        • 1970-01-01
        • 1970-01-01
        • 2017-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多