【问题标题】:TControl (child) to TObject and set its Parent property via RTTI or SetXXXXXXPropertyTControl (child) 到 TObject 并通过 RTTI 或 SetXXXXXXProperty 设置它的 Parent 属性
【发布时间】:2014-10-14 07:21:07
【问题描述】:

目前在delphi中做一些RTTI的研究。

出现的问题如下。

对于这个例子,我有一个 TPanel 组件(由代码创建,所有者由调用方法传递)现在 TPanel 被强制转换为 TObject(以保持我使用的方法通用)。

现在我尝试通过 SetXXXXXXProp 函数设置该属性(XXXXXX 是以下任何一种(ord、variant、str、method...。基本上我尝试了所有 SetProperty 函数。)

但出于某种奇怪的原因,我收到的消息是没有 Parent 属性。 如何设置我的 Parent 属性??

所以我希望你们中的任何人都可以给我一个正确方向的“指针”。

class procedure TComponentsCreator.AddParent(obj, parent : TObject);
var
  count : integer;
  propList: PPropList;
  I: Integer;

  method : TMethod;
begin

  count := GetPropList(obj, propList);

  for I := 0 to count -1 do
    begin

      WriteLn(propList[i]^.Name);

      if (CompareStr(LowerCase(String(propList[i]^.Name)), LowerCase('Parent')) = 0) then
        begin
          SetObjectProp(obj, String(propList[i]^.Name), parent);
        end;
    end;
end;    

【问题讨论】:

  • 取决于你的问题,但可能根本不需要使用 RTTI,只需使用 TControl.Parent。
  • 你为什么不显示演示问题的代码。我们现在应该猜到你做了什么吗?
  • 你的权利,大卫,我马上去拿它:-)
  • 您的意思是 for 循环中的 count-1?
  • 大卫为什么要立即删除我的帖子???在您发布消息后的 2 分钟内,我已经发布了我的代码……一个人不会忘记什么吗?

标签: delphi properties rtti


【解决方案1】:

您正在使用为 .dfm 流媒体机制设计的旧式 RTTI。当您调用GetPropList 时,返回的列表包含已发布的属性。您正在寻找已公开但未发布的Parent

您可以使用新样式的 RTTI 来实现这一点,但这似乎是不必要的。当您希望操作的成员或类型在编译时未知时,需要 RTTI。但是,您确实认识该成员。它是TControl.Parent。所以你可以写

(obj as TControl).Parent := parent;

如果由于某种原因,您不得不使用 RTTI,那么我能找到的最简单的代码编写方法是:

procedure SetControlParent(obj, parent: TObject);
var
  ctx: TRttiContext;
  typ: TRttiType;
  prop: TRttiProperty;
begin
  typ := ctx.GetType(obj.ClassType);
  prop := typ.GetProperty('Parent');
  prop.SetValue(obj, parent);
end;

我在这里省略了任何错误检查,但我希望您不会在实际代码中做同样的事情。


除了未成年人,您对CompareStr 的调用是不必要的复杂。如果您希望使用不区分大小写的比较,请使用CompareText。如果您想比较是否相等,请使用SameText。您可以像这样更清楚、更简单地替换该代码:

if SameText(propList[I]^.Name, 'Parent') then

【讨论】:

  • 正如我在之前的评论中已经说过的那样。我已经使用了我在 stackoverlow 上找到的这个链接中的修复程序。 stackoverflow.com/questions/16948114/…
  • 很难看出这个问题与这个问题有什么关系。也很难理解为什么要在编译时知道的东西上使用 RTTI。
  • 在 TPanel 的情况下,我实时知道这一点,但如果我使用多个其他组件,那么我会发现自己正在重写和检查与 TControl/TWinControl 的关系的所有内容。那是我不打算做的事情。无论如何,现在一切正常。
  • 你不需要知道它是一个面板。但你知道它是TControl。因为否则Parent 毫无意义。所以你确实知道在编译时需要知道什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2011-11-30
相关资源
最近更新 更多