PDA

Ver la Versión Completa : Asignar dinámicamente valores a propiedades sin conocer previamente cuáles


Leviatan
25-01-2012, 01:35:52
Hola amigos:

Necesito leer datos de un XML de configuración que contiene básicamente la siguiente estructura:

<parametros> <edPuerto>
<Text>80</Text>
...
...
</edPuerto>
...
...
</parametros>

El tag "edPuerto" es de un tipo TEdit en la aplicación y el nodo hijo "Text" es la propiedad que necesito asignar. Al ejecutarse, la app leerá el archivo de configuración XML y asignará el valor "80" a la propiedad "Text" de "edPuerto".

Se podrían ir añadiendo propiedades al XML y la idea es asignar aquellas propiedades que se definan en el archivo de configuración. ¿Cómo lo puedo hacer?

Muchas gracias de antemano.

LoPiTaL
25-01-2012, 15:52:40
Si estás trabajando con Delphi 2010 o superior, puedes hacerlo fácilmente usando la unit RTTI, mediante el objeto TRttiContext. Busca en google más info sobre éste y encontrarás mucha información sobre él, cómo leer / escribir propiedades por nombre, etc...

Por ejemplo:

procedure SetProperty(propname: string; value: TValue; obj: TMyObject);
var
context: TRTTIContext;
rtti: TRTTIType;
prop: TRTTIProperty;

begin
context := TRTTIContext.Create;
rtti := context.GetType(TMyObject);
prop := rtti.GetProperty(propname);
prop.SetValue(obj, value);
end;




Sólo deberás tener cuidado con el tipo de la propiedad. Si es string, deberás pasarle un string a value, si es int, deberás pasarle un int, etc...

Si estás trabajando con una versión anterior, la cosa se complica un poco, pero sigue siendo posible. Google te lanzará mucha información si buscas "RTTI".

En cuanto a encontrar componentes en un form, simplemente sería haciendo

for I:=0 to ComponentsCount - 1 do begin
if Components[I].Name=TuNombreLeido then begin
//Aquí iría la rutina para establecer el valor de la propiedad en cuestión.
seteaPropiedad(nombrePropiedad, Components[I])
end;
end;

Un saludo,
LoPiTaL

ecfisa
25-01-2012, 16:55:17
Hola.

Con Delphi 7 y superior podrías hacer algo como:

...
implementation

uses TypInfo;

procedure TForm1.CambiarPropiedad(const AName, AProperty, AValue: string);
var
PInfo: PPropInfo;
TC: TComponent;
begin
TC:= FindComponent(AName);
PInfo:= GetPropInfo(TC.ClassInfo, AProperty);
if PInfo <> nil then
begin
case PInfo^.Proptype^.Kind of
tkString, tkLString: SetStrProp(TC, PInfo, AValue);
tkInteger: if (PInfo^.PropType^.Name = 'TColor') then
SetOrdProp(TC, PInfo, StringToColor(AValue))
else if (PInfo^.PropType^.Name = 'TCursor') then
SetOrdProp(TC, PInfo, StringToCursor(AValue))
else
SetOrdProp(TC, PInfo, StrToInt(AValue));
tkEnumeration: try
if (PInfo^.PropType^ = TypeInfo(System.Boolean)) then
SetOrdProp(TC, PInfo, StrToInt(AValue))
else
SetOrdProp(TC, PInfo, StrToInt(AValue));
except
raise;
end;
end;
end;
end;


Ejemplo de uso:

CambiarPropiedad('edPuerto', 'Text', 'Hola');
CambiarPropiedad('edPuerto', 'Color', 'clLime');
CambiarPropiedad('edPuerto', 'Cursor', 'crHandPoint');
...


Saludos.

Leviatan
25-01-2012, 23:58:11
Hola amigos,

Gracias por su respuesta. Estoy usando Delphi 2010. Lo voy a probar y les cuento cómo me fue.

Saludos.

Leviatan
31-01-2012, 00:34:59
Gracias LoPiTaL y ecfisa. Los ejemplos que me han pasado me han funcionado super bien.

Saludos