Ali*_*ter 6 delphi rtti delphi-10.4-sydney
当在 VCL 控件上调用 TRttiContext.GetType 时,为什么某些属性会重复(例如Action和Align),而其他属性则不会 ( 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;
Run Code Online (Sandbox Code Playgroud)
输出
动作 : TBasicAction = (空) 动作 : TBasicAction = (空) 对齐:TAlign = alNone 对齐:TAlign = alNone AlignDisabled : Boolean = False AlignWithMargins : Boolean = False 锚点:TAnchors = [akLeft,akTop] 锚点:TAnchors = [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;
Run Code Online (Sandbox Code Playgroud)
上面的代码产生:
TButton的.Action:TBasicAction =(空)
的TControl .Action:TBasicAction =(空)
的TControl .align伪:TAlign = alNone
TButton的.align伪:TAlign = alNone
TWinControl .AlignDisabled:布尔=假
的TControl .AlignWithMargins:布尔=假
的TControl .Anchors: TAnchors = [akLeft,akTop]
TButton的.Anchors:TAnchors = [akLeft,akTop]
TButton的.BiDiMode:TBiDiMode = bdLeftToRight
的TControl .BiDiMode:TBiDiMode = bdLeftToRight
...
现在您可以清楚地看到,它GetProperties枚举了在具有更高可见性或更改顺序的后代类中重新引入的属性。当以可见性TCustomMyControl定义并在级别重新引入它时,这对于控件来说是典型的。SomePropertyprotectedTMyControlpublished
您可以尝试TButton在TForm11声明之前添加内插器类:
type
TButton = class(Vcl.StdCtrls.TButton)
published
property AlignWithMargins;
end;
Run Code Online (Sandbox Code Playgroud)
输出将反映变化。我添加了属性声明类型的完全限定名称 ( Prop.Parent.QualifiedName) 以使其更明显地TButton来自我自己的单元。
Vcl.StdCtrls.TButton.Action : TBasicAction = (空)
Vcl.Controls.TControl.Action : TBasicAction = (空)
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.锚点:TAnchors = [akLeft,akTop]
Vcl.StdCtrls.TButton.BiDiMode:TBiDiMode = bdLeftToRight
Vcl.Controls.TControl.BiDiMode:TBiDiMode = bdLeftToRight
...
这种行为不仅限于控件。可以在任何从祖先类中重新引入属性的类上观察到。
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |