2011-11-23 16 views
7

Ho una classe con oggetti di scena pubblicati che serializzo in XML.Ottieni un valore di attributo di proprietà specifica

MyAttr = class(TCustomAttribute) 
private 
    FName: string; 
public 
    constructor Create(const Name: string); 
    property Name: string read FName write FName; 
end; 

MyClass = class(TPersistent) 
private 
    FClassCaption: string; 
published 
    [MyAttr('Class')] 
    property ClassCaption: string read FClassCaption write FClassCaption; 
end; 

Dal formato XML è fondamentale, io uso gli attributi di dare nome più breve per la proprietà (cioè non riesco a definire una proprietà denominata 'Classe'). serializzazione implementata in questo modo:

lPropCount := GetPropList(PTypeInfo(Obj.ClassInfo), lPropList); 
for i := 0 to lPropCount - 1 do begin 
    lPropInfo := lPropList^[i]; 
    lPropName := string(lPropInfo^.Name); 

    if IsPublishedProp(Obj, lPropName) then begin 
    ItemNode := RootNode.AddChild(lPropName); 
    ItemNode.NodeValue := VarToStr(GetPropValue(Obj, lPropName, False)); 
    end; 
end; 

ho bisogno di condizione come: se la proprietà segnati MyAttr, ottenere "MyAttr.Name" invece di "lPropInfo^.Name".

risposta

5

È possibile utilizzare questa funzione per ottenere il vostro nome attributo dalla data proprietà (lo ha scritto in un minuto, probabilmente ha bisogno di qualche ottimizzazione):

uses 
    SysUtils, 
    Rtti, 
    TypInfo; 

function GetPropAttribValue(ATypeInfo: Pointer; const PropName: string): string; 
var 
    ctx: TRttiContext; 
    typ: TRttiType; 
    Aprop: TRttiProperty; 
    attr: TCustomAttribute; 
begin 
    Result := ''; 

    ctx := TRttiContext.Create; 

    typ := ctx.GetType(ATypeInfo); 

    for Aprop in typ.GetProperties do 
    begin 
    if (Aprop.Visibility = mvPublished) and (SameText(PropName, Aprop.Name)) then 
    begin  
     for attr in AProp.GetAttributes do 
     begin 
     if attr is MyAttr then 
     begin 
      Result := MyAttr(attr).Name; 
      Exit; 
     end; 
     end; 
     Break; 
    end; 
    end; 
end; 

chiamare in questo modo:

sAttrName:= GetPropAttribValue(obj.ClassInfo, lPropName); 

Quindi, se questa funzione restituisce una stringa vuota, significa che la proprietà non è contrassegnata con MyAttr e quindi è necessario utilizzare "lPropInfo^.Name".

Problemi correlati