[ looping @ 04.08.2014. 14:54 ] @
Pozdrav,
Koristim RTTI da bih u RunTime-u dobio sve property-e nekog objekta i to znam kako da uradim za property-e prostih tipova (string, integer ...),
medjutim, ako imam property tipa neke klase i zelim da dobijem vrednost nekog polja te klase (na pr. TStringList tip polja) onda ne mogu nista da dobijem.
Da li neko ima ideju kako da dobijem vrednost slozenog propertija?
[ reiser @ 04.08.2014. 15:54 ] @
Imas vec gotovo resenje: http://code.google.com/p/delphi-oop/wiki/SvSerializer

A ako hoces sam:

Code:

{$APPTYPE CONSOLE}

uses
  System.Classes, System.Rtti, System.TypInfo;

procedure PrintStringList(const AObject: TObject);
var
  t: TRttiType;
  p: TRttiProperty;
  m: TRttiMethod;
  C1, count: Integer;
begin
  t := TRttiContext.Create.GetType(AObject.ClassType);
  p := t.GetProperty('Count');
  m := t.GetMethod('Get');
  if (Assigned(p)) and (Assigned(m)) then
  begin
    count := p.GetValue(AObject).AsInteger;
    for C1 := 0 to count - 1 do
      WriteLn(m.Invoke(AObject, [C1]).ToString);
  end;
end;

var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add('text 1');
    sl.Add('text 3');
    sl.Add('text 2');
    PrintStringList(sl);
  finally
    sl.Free;
  end;
end.


Nisam siguran gde ti skripi, tako da je najbolje da postujes specificniji problem ili kod, pa ces dobiti i bolju pomoc.
[ looping @ 04.08.2014. 16:48 ] @
Mozda sam bio malo nejasan, jer je problem u ugnjezdenom propertiju,
na pr
Code:

myContrl.SomeProperty.myValue

Kako da dodjem do myValue?
[ reiser @ 04.08.2014. 16:54 ] @
Sa GetProperty() dobijas property, sa GetMethod() dobijas metodu, ako hoces da dobijes vrednost propertija, onda pozivas p.As*, gde je p TRttiProperty koji si prethodno dobio preko GetProperty(). Pogledaj kod iznad koji sam postovao, tu imas sve sto ti treba.
[ looping @ 04.08.2014. 19:38 ] @
Konkretan problem je sledeci:
Imam kontrolu tipa TStringGridExtended koja je nasledjena od kontrole TStringGrid
Kontrola ima property CustomEdits (tipa TCustomEdits koja nasledjuje od TPersistent klase) i sadrzi property-e Names tipa TStringList, Columns tipa TFilterDropDownColumns ...

Code:

r := ctx.GetType(TStringList);
p := r.GetProperty('Count');
m := r.GetMethod('Get');
count := p.GetValue((myStringGrid)).AsInteger; //Ovo pukne jer ne znam kako da prosledim konkretan objekat (TStringList) a ne celu kontrolu


[ reiser @ 04.08.2014. 23:31 ] @
TStringList nadjes na slican nacin kao i propertije/metode:

Code:

{$APPTYPE CONSOLE}

uses
  System.Classes, Vcl.Grids, System.Rtti, System.TypInfo;

type
  TCustomEdits = class(TPersistent)
  private
    FNames: TStringList;
  public
    constructor Create;
    destructor Destroy; override;
    property Names: TStringList read FNames;
  end;

  TStringGridExtended = class(TStringGrid)
  private
    FCustomEdits: TCustomEdits;
  public
    constructor Create; reintroduce;
    destructor Destroy; override;

    property CustomEdits: TCustomEdits read FCustomEdits;
  end;

{ TStringGridExtended }

constructor TStringGridExtended.Create;
begin
  inherited Create(nil);
  FCustomEdits := TCustomEdits.Create;
end;

destructor TStringGridExtended.Destroy;
begin
  FCustomEdits.Free;
  inherited;
end;

{ TCustomEdits }

constructor TCustomEdits.Create;
begin
  FNames := TStringList.Create;
end;

destructor TCustomEdits.Destroy;
begin
  FNames.Free;
  inherited;
end;

procedure PrintStringList(const AObject: TObject);
 var
   t: TRttiType;
   p: TRttiProperty;
   m: TRttiMethod;
   C1, count: Integer;
 begin
   t := TRttiContext.Create.GetType(AObject.ClassType);
   p := t.GetProperty('Count');
   m := t.GetMethod('Get');
   if (Assigned(p)) and (Assigned(m)) then
   begin
     count := p.GetValue(AObject).AsInteger;
     for C1 := 0 to count - 1 do
       WriteLn(m.Invoke(AObject, [C1]).ToString);
   end;
 end;

var
  sge: TStringGridExtended;
  c: TRttiContext;
  p1, p2: TRttiProperty;
  v1, v2: TValue;
begin
  sge := TStringGridExtended.Create;
  try
    sge.CustomEdits.Names.Add('text 1');
    sge.CustomEdits.Names.Add('text 3');
    sge.CustomEdits.Names.Add('text 2');

    c := TRttiContext.Create;
    p1 := c.GetType(sge.ClassType).GetProperty('CustomEdits');
    if Assigned(p1) then
    begin
      p2 := c.GetType(p1.PropertyType.Handle).GetProperty('Names');
      if Assigned(p2) then
      begin
        v1 := p1.GetValue(sge);
        v2 := p2.GetValue(v1.AsObject);
        PrintStringList(v2.AsObject);
      end;
    end;
  finally
    sge.Free;
  end;

  ReadLn;
end.


Referenca: http://docwiki.embarcadero.com/Libraries/XE3/en/System.Rtti
[ looping @ 05.08.2014. 10:42 ] @
Hvala na pomoci, uspeo sam uz pomoc prikazanog koda