目前正在对delphi中的RTTI进行一些研究。
出现的问题如下。
对于这个例子,我有一个TPanel组件(从代码创建,所有者通过invoke方法传递)现在TPanel被强制转换为TObject(以保持我使用的通用方法)。
现在我尝试通过SetXXXXXXProp函数设置该属性(XXXXXX是以下任何一种(ord,variant,str,方法......基本上我尝试了所有的SetProperty函数。)
但由于一些奇怪的原因,我收到的消息是没有父属性。 如何设置父属性?
所以我希望你们中的任何一个人都能在正确的方向上给我一个“指针”。
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;
答案 0 :(得分: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