RTTI Riempire una lista con un tipo enumerabile

di il
1 risposte

RTTI Riempire una lista con un tipo enumerabile

Salve a tutti.
Sto costruendo un "form builder" con dei componenti custom e per editare le varie property ho costruito anche un "simil" object inspector usando RTTI che delphi mette a disposizione, in poche righe ad ogni click sul componente selezionato riempo una string grid con le varie property

var
  ctx: TRttiContext;
  objType: TRttiType;
  Prop: TRttiProperty;
begin
  ctx := TRttiContext.Create;
  objType := ctx.GetType(oPropertyComp.ClassInfo);
  for Prop in objType.GetProperties do
  begin
     aValue := Prop.GetValue(Pointer(oPropertyComp));
     sgProp.Cells[0, nInc - 1] := Prop.Name;
     sgProp.Cells[1, nInc - 1] := aValue.ToString;
     Inc(nInc);
     sgProp.RowCount := nInc;
  end;
  ....
end;  
e sino a qui, un po' rozzo, ma tutto bene, i problemi arrivano quando cerco di modificare una property "enum", nella cella selezionata creo un combo e dentro vorrei metterci tutte le scelte possibili, ma usando la unit RTTI non riesco a trovare la strada, e ho dovuto ripiegare usando la unit TypeInfo facendo:

var p: PByte;
     AValue: TValue;
     i: integer;
begin
// ricavo in AValue la property con RTTI e se aValue.TypeInfo.Kind è tkEnumeration
     // usando typoinfo mi vado a prendere la lista dei enum della property
      p := @System.TypInfo.GetTypeData(aValue.TypeData^.BaseType^)^.NameList;
      // poi riusando la uniRTTI riempo il combo con i vari Item e lo mostro nella cella selezionata
      for i := 0 to aValue.TypeData.MaxValue  do
         ComboEnum.Items.Add(ReadShortString(p));

end 

Il tutto funziona abbastanza bene (devo fare qualche altro test, ma sono ottimista).
La mia curiosita è: come estrarre i type di una property usando solo la unit RTTI, senza doversi appoggiare al typeinfo, se possibile.
W.

1 Risposte

  • Re: RTTI Riempire una lista con un tipo enumerabile

    Grazie a http://doh.collegedenhulster.nl/_inf/delphi/CodinginDelphi.pdf sono riuscito a risolvere.
    
    var  Context:TRttiContext;
           TempType:TRttiType;
           TempEnum: TRttiEnumerationType;
           aListaProp: TArray<String>;
           i: Integer;
    begin
    .... in aVAlue che è di tipo TValue ho i miei dati
      Context := TRttiContext.Create;
      TempType := Context.GetType(aValue.TypeData^.BaseType^); // mi prendo il tipo
      TempEnum := TempType as TRttiEnumerationType;  // faccio un cast alla classe TRttiEnumerationType 
      aListaProp := TempEnum.GetNames;  // la classe TRttiEnumerationType espone il metodo Getnames che è quello che mi serve
      for i := low(aListaProp) to High(aListaProp)  do // poi un semplice loop sull'array di ritono per riempire il combo
        oCombo.Items.Add(aListaProp[i]);         
    
Devi accedere o registrarti per scrivere nel forum
1 risposte