gpt4 book ai didi

delphi - 为什么在VCL控件上调用TRttiContext.GetType时会重复某些属性?

转载 作者:行者123 更新时间:2023-12-03 09:56:28 30 4
gpt4 key购买 nike

当在VCL控件上调用TRttiContext.GetType时,为什么要重复某些属性(例如ActionAlign),而其他属性则不重复(AlignWithMargins)?

uses
System.RTTI,
System.Generics.Collections,
System.Generics.Defaults;

//....

procedure TForm11.btnShowPropertiesClick(Sender: TObject);
var
R: TRttiContext;
Props: TArray<TRttiProperty>;
Prop : TRttiProperty;
begin
memo1.Clear;
R := TRttiContext.Create;
Props := R.GetType(Sender.ClassType).GetProperties;

//Sort properties by name
TArray.Sort<TRttiProperty>(props,
TComparer<TRttiProperty>.Construct(
function(const Left, Right: TRttiProperty): Integer
begin
result := CompareText(Left.Name, Right.Name);
end
)
);

for prop in Props do
begin
try
Memo1.Lines.Add(
Prop.Name + ' : ' +
Prop.PropertyType.ToString + ' = ' +
Prop.GetValue(Sender).ToString);
except
Memo1.Lines.Add(Prop.Name + ' generated an exception');
end;
end;
end;
输出
Action :TBasicAction =(空)
Action :TBasicAction =(空)
对齐:TAlign = alNone
对齐:TAlign = alNone
AlignDisabled: bool 值=否
AlignWithMargins: bool 值=否
anchor : anchor = [akLeft,akTop]
anchor : anchor = [akLeft,akTop]
BiDiMode:TBiDiMode = bdLeftToRight
BiDiMode:TBiDiMode = bdLeftToRight
...

最佳答案

如果您将Prop.Parent.Name添加到填充备忘录的循环中,则可以很容易地找到原因:

for prop in Props do
begin
try
Memo1.Lines.Add(
Prop.Parent.Name + '.' + { added }
Prop.Name + ' : ' +
Prop.PropertyType.ToString + ' = ' +
Prop.GetValue(Sender).ToString);
except
Memo1.Lines.Add(Prop.Name + ' generated an exception');
end;
end;
上面的代码产生:

TButton.Action : TBasicAction = (empty)
TControl.Action : TBasicAction = (empty)
TControl.Align : TAlign = alNone
TButton.Align : TAlign = alNone
TWinControl.AlignDisabled : Boolean = False
TControl.AlignWithMargins : Boolean = False
TControl.Anchors : TAnchors = [akLeft,akTop]
TButton.Anchors : TAnchors = [akLeft,akTop]
TButton.BiDiMode : TBiDiMode = bdLeftToRight
TControl.BiDiMode : TBiDiMode = bdLeftToRight
...


现在,您可以清楚地看到 GetProperties 枚举了具有更高可见性或更改顺序的后代类中重新引入的属性。当 TCustomMyControlSomeProperty可见性定义 protected并在 TMyControl级别重新引入 published时,这对于控件来说是典型的。
您可以尝试在 TButton声明之前为 TForm11添加插入器类:
type
TButton = class(Vcl.StdCtrls.TButton)
published
property AlignWithMargins;
end;
输出将反射(reflect)更改。我添加了属性声明类型的全限定名称( Prop.Parent.QualifiedName),以使 TButton来自我自己的单元更加明显。

Vcl.StdCtrls.TButton.Action : TBasicAction = (empty)
Vcl.Controls.TControl.Action : TBasicAction = (empty)
Vcl.Controls.TControl.Align : TAlign = alNone
Vcl.StdCtrls.TButton.Align : TAlign = alNone
Vcl.Controls.TWinControl.AlignDisabled : Boolean = False
Vcl.Controls.TControl.AlignWithMargins : Boolean = False
Unit1.TButton.AlignWithMargins : Boolean = False
Vcl.Controls.TControl.Anchors : TAnchors = [akLeft,akTop]
Vcl.StdCtrls.TButton.Anchors : TAnchors = [akLeft,akTop]
Vcl.StdCtrls.TButton.BiDiMode : TBiDiMode = bdLeftToRight
Vcl.Controls.TControl.BiDiMode : TBiDiMode = bdLeftToRight
...


这种行为不仅限于控件。可以在从祖先类重新引入属性的任何类中观察到它。

关于delphi - 为什么在VCL控件上调用TRttiContext.GetType时会重复某些属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63983114/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com