tcxbalage
tcxbalage

Reputation: 726

using GetPropInfo on public property

As I understand since the Delphi 2010 I would be able to use RTTI not only on published, but on public property too. I had an old Delphi 7 code, which working under XE7 too, but I'm still unable to access public properties.

Here is the code:

uses
  System.TypInfo;

procedure TForm1.GetPublicProp;
var
  AColumn: TcxGridDBColumn;
  APropInfo: PPropInfo;
begin
  AColumn := MycxGridDBTableView.Columns[0];
  APropInfo := GetPropInfo(AColumn, 'Index');
  if (APropInfo = nil) then
    showmessage('not found');
end;

(The TcxGridDBColumn is a column in a TcxGrid > DevExpress component)

Obviously I missed something or I completely misunderstood how the RTTI works under XE and there is still no access to public properties?

Upvotes: 4

Views: 1700

Answers (1)

GolezTrol
GolezTrol

Reputation: 116140

A snippet that uses the new TRTTIContext record as an entry point to get the type and then its properties.

Note that it doesn't explicitly need the TypInfo unit. You get the RTTIType using the original PTypeInfo, but you can just pass AnyObject.ClassType and it will be treated as a PTypeInfo.

From the type, you can get an array of properties, which I believe you have to iterate to find the right one.

uses
  System.Rtti;

type
  TColumn = class
  private
    FIndex: Integer;
  public
    property Index: Integer read FIndex write FIndex;
  end;

var
  AnyObject: TObject;
  Context: TRttiContext;
  RType: TRttiType;
  Prop: TRttiProperty;
begin
  AnyObject := TColumn.Create;
  TColumn(AnyObject).Index := 10;

  try
    // Initialize the record. Doc says it's needed, works without, though.
    Context := TRttiContext.Create;

    // Get the type of any object
    RType := Context.GetType(AnyObject.ClassType);

    // Iterate its properties, including the public ones.
    for Prop in RType.GetProperties do
      if Prop.Name = 'Index' then
      begin
        // Getting the value.
        // Note, I could have written AsInteger.ToString instead of StrToInt.
        // Just AsString would compile too, but throw an error on int properties.
        ShowMessage(IntToStr(Prop.GetValue(AnyObject).AsInteger));

        // Setting the value.
        Prop.SetValue(AnyObject, 30);
      end;
  finally
    AnyObject.Free;
  end;
end;

Upvotes: 4

Related Questions