How to traverse a property of type TObjectList via Rtti?

7

My class has a property of type TObjectList:

TBaseModelo = class(TInterfacedPersistent)
public
    property ListaCamposValidacao: TObjectList<TCampoValidacao> read FListaCamposValidacao write FListaCamposValidacao;
end;

I need, through RTTI, to select this property "PadValidation List" and go through it to do an action, however I have no idea how to do it.

Ctx := TRttiContext.Create;
try
  Typ := Ctx.GetType(Objeto.ClassType);      
  ????? 
  //Typ.GetProperty('ListaCamposValidacao').GetValue(Objeto);
finally
  Ctx.Free;
end;

Can anyone help me, guide me in how to implement the code?

    
asked by anonymous 26.11.2014 / 18:12

1 answer

1

Here is a simple example of how to walk through a property of type TObjectList<T> , there are undoubtedly many other ways to accomplish this task, as the purpose here is to show the path and simplicity is the best option. This example is not validating properties ie no access methods getters&setters is writing and reading everything straight from instance variables campos/atributos da classe

unit FrmPrincipal;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Generics.Collections, System.Rtti;

type

   TCampoValidacao = class
    private
      FId: string;
      FNome: string;
      FEndereco: string;
      FBairro: string;
    public
      property Id: string read FId write FId;
      property Nome: string read FNome write FNome;
      property Endereco: string read FEndereco write FEndereco;
      property Bairro: string read FBairro write FBairro;
   end;

   TBaseModelo = class(TInterfacedObject)
  private
    FListaCamposValidacao: TObjectList<TCampoValidacao>;
  public
      property ListaCamposValidacao: TObjectList<TCampoValidacao> read FListaCamposValidacao write FListaCamposValidacao;
      constructor Create;
      destructor Destroy; override;
  end;

  TModeloX = Class(TBaseModelo )
    private
    FId:string;
    FNome: string;
    FEndereco: string;
    FBairro: string;
    public
      property Id: string read FId write FId;
      property Nome: string read FNome write FNome;
      property Endereco: string read FEndereco write FEndereco;
      property Bairro: string read FBairro write FBairro;
  End;

  TForm1 = class(TForm)
    btGerar: TButton;
    Memo1: TMemo;
    procedure btGerarClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btGerarClick(Sender: TObject);
var
    id: TGuid;
    meuModelo:  TModeloX;
    campoValidacao: TCampoValidacao;
    ctxRtti  : TRttiContext;
    typeRtti : TRttiType;
    propRtti : TRttiProperty;
    I: Integer;
begin
   meuModelo := TModeloX.Create;
   for I := 0 to 50 do
   begin
     CreateGUID(id);
     campoValidacao := TCampoValidacao.Create;
     campoValidacao.Id := System.SysUtils.GUIDToString( id );
     campoValidacao.Nome := 'MAURO' + IntToStr( i );
     campoValidacao.Endereco := 'RUA PEDRO PEREIRA - Nº ' + IntToStr( i );
     campoValidacao.Bairro := 'Vila Martins ';
     meuModelo.ListaCamposValidacao.Add(campoValidacao);
   end;
   campoValidacao := nil;

   ctxRtti  := TRttiContext.Create;

   for campoValidacao in meuModelo.ListaCamposValidacao do
   begin
     typeRtti := ctxRtti.GetType( campoValidacao.ClassType );
     for propRtti in typeRtti.GetProperties do
       Memo1.Lines.Add( propRtti.Name+': ' +  propRtti.GetValue( campoValidacao).ToString );
   end;
  ctxRtti.Free;
end;

{ TBaseModelo }

constructor TBaseModelo.Create;
begin
  FListaCamposValidacao := TObjectList<TCampoValidacao>.Create;
end;

destructor TBaseModelo.Destroy;
begin
  if Assigned( FListaCamposValidacao ) then
    FListaCamposValidacao.Free;
  inherited;
end;

end.

Search source: link

    
23.05.2015 / 11:16