Ver Mensaje Individual
  #1  
Antiguo 13-09-2012
elarys elarys is offline
Miembro
 
Registrado: abr 2007
Posts: 94
Reputación: 18
elarys Va por buen camino
¿Cómo 'casteo' un TCollection?

Tengo mi Objeto es algo asi simplificado

Código Delphi [-]
  TCodes = class (TPersistent)
  protected
    FCode: Integer;
    FName: String;
    FTipo: TATS_List; 

  published
    property Code: Integer read FCode write FCode;
    property Name: String read FName write FName;
    property Tipo: TATS_List read FTipo write FTipo;
  end;

Y en donde TATS_List es una coleccion de objetos
Ahora con el siguiente procedimiento leo las propiedades de dicho objeto
Nambre y valores

Pero cuando llega al TATS_List que es de tipo TCollection, no lee y pasa al siguiente elemento

Puedo castear, sabiendo que TATS_List es de tipo TCollection
y obtener los valores de esa forma???

Código Delphi [-]
procedure GetPropertyObject(Obj: TObject; List: TStringList; Counter: Integer);
var
  Names, Value, cName, prueba: String;
  PInfo: PPropInfo;
  PropList: PPropList;
  Count, i, j: Integer;
  Ob: TObject;
begin
  Count := GetPropList(Obj.ClassInfo, tkProperties, nil);
  GetMem(PropList, Count * SizeOf(PPropInfo));
  GetPropList(Obj.ClassInfo, tkProperties, PropList);

  cName := Obj.ClassName;
  Delete(cName, 1, 1);
  List.Add('<' + cName + '>');

  for i := 0 to Count -1 do
  begin
    Value := GetPropValue(Obj, Proplist[i].Name);
    PInfo := GetPropInfo(Obj, Proplist[i].Name);
    Names := Proplist[i].Name;

    if PInfo <> nil then
    begin
      if PInfo^.PropType^.Kind = tkClass then
      begin
        Ob := GetObjectProp(Obj, Proplist[i].Name);

        if Ob is TCollection then
        begin
          //AQUI QUIERO HACER CAST PARA DEVOLVER LOS VALORES QUE TIENE
          //LO QUE SE QUE ES DE TIPO TCollection;
          //COMO OBTENGO LOS NOMBRES Y VALORES DENTRO DE ESTE
        end
        else
        begin
          GetPropertyObject(Ob, List, Counter + 1);
        end;

      end
      else
      begin
        List.Add('<' + Names + '>' + Value + ' + Names + '>');
      end;
    end;
  end;
  List.Add(' + cName + '>');
end;

Por el momento esto me devuelve un stringlist y los datos de mi objeto simplificado para no hacerlo largo y que se entienda
Noten que Tipo que seria mi TCollection RTTI o TypInfo no lee los datos, siendo que mi objeto si tiene datos
<Codes>
<Code>1</Code>
<Name>A</Name>
<Tipo></Tipo>
<Code>2</Code>
<Name>B</Name>
<Tipo></Tipo>
<Code>3</Code>
<Name>C</Name>
<Tipo></Tipo>
</Codes>

Mi idea es castear el TCollection para ver si de ahi puedo leer los datos, pero si hay alguna otra manera bienvenida sea
La clase TATS_List funciona correctamente, y me carga los datos a mi objeto...
Luego le paso al procedure mi objeto en tiempo de ejecucion y que haga el trabajo, pero nada

Edito porque hice nuevas pruebas
NOTA: probe pasando todo mi codigo TCollection con un TStringList, con un TList, TStrings, etc, etc, debe ser porque ninguno de estos tienen propiedad published, se les ocurre algun otro contenedor de objetos, o similares como stringlist
Parece que RTTI no lee propiedades publicas.

Acabo de hacer otra prueba, agregando un nuevo valor simulando que es mi collection pero ahora de un solo campo de tipo Array of String
Al ser public Items mi procedimiento no lo puede leer
Probe pasarlo a published, pero delphi me da error Items no puede ser published por ser un array
Estoy trabajando con delphi 2007 y por ahora no podemos mudarnos si tienen soluciones con delphi mas nuevos

Código Delphi [-]
  TCodes = class (TPersistent)
  protected
    FCode: Integer;
    FName: String;
    FTipo: TATS_List;
 
    FItems: Array of String;

    procedure SetItems(Index: Integer; Value: String);
    function GetItems(Index: Integer): String;

  public
    function Add(Str: String): Integer;
    property Items[Index: Integer]: String read GetItems write SetItems;

  published
    property Code: Integer read FCode write FCode;
    property Name: String read FName write FName;
    property Tipo: TATS_List read FTipo write FTipo;
  end;

implementation

function TCodes.Add(Str: String): Integer;
begin
  SetLength(FItems, Length(FItems) + 1);
  FItems[Length(FItems) - 1] := Str;
  Result := Length(FItems) - 1;
end;

procedure TCodes.SetItems(Index: Integer; Value: String);
begin
  FItems[Index] := Value;
end;

function TCodes.GetItems(Index: Integer): String;
begin
  Result := FItems[Index];
end;

Última edición por elarys fecha: 13-09-2012 a las 21:17:26.
Responder Con Cita