PDA

Ver la Versión Completa : Asignación dinámica de propiedades


Mariana
17-10-2005, 15:19:10
Hola a todos, en este caso mi pregunta es la siguiente:

Tengo un form con varios componentes, botones, edits, etc.
Por otro lado tengo una tabla donde se listan las propiedades de cada uno: color, tamaño, posición, etc. y los valores que estas deberían tomar, es decir, la tabla tiene la siguiente forma (tipo_componente, nombre_propiedad, valor_propiedad), por ejemplo (TLabel, color, clred).
Mi pregunta es la siguiente, cuando manejo un componente y le quiero cambiar el valor a una propiedad direntamente hago lo siguiente:
nombre_componente.nombre_propiedad:= nuevo_valor,
pero ahora lo que necesito es sacar nombre_componente y valor de la tabla,
es decir, poder escribir:
nombre_componente.(nombre de la propiedad sacado de la tabla):= valor
, en el caso de valor solo tengo que asignar el campo, lo que no se como se hace es la referencia a la propiedad.
desde ya agradezco su ayuda, como siempre.

Neftali [Germán.Estévez]
17-10-2005, 15:39:58
Creo que para eso puedes utilizar RTTI.
Te acnsejo que busques entre los fuentes de Delphi la unit llamada TypInfo.pas y le eches un vistazo (normalmente en el directorio ...\sources\rtl\common de Delphi)
Verás que puedes encontrar procedimientos interesantes.

Yo utilizo el siguiente:


{:Asigna valor a una propiedad a través del Nombre (RTTI). }
function SetPropAsString(AObj: TObject; const PropName, Value: String):Boolean;
var
PInfo: PPropInfo;
Begin
// Intentamos acceder (con un puntero) a la info. de la propiedad
PInfo := GetPropInfo(AObj.ClassInfo, PropName);
Result := PInfo <> nil;

// Se ha obtenido la información...
if (Result) then begin
// Se ha encontrado la propiedad con éste nombre; Chequear el tipo...
if (PInfo^.Proptype^.Kind = tkString) or
(PInfo^.Proptype^.Kind = tkLString) then begin
// Asignar el valor de tipo String
SetStrProp(AObj, PInfo, Value);
end
else if (PInfo^.Proptype^.Kind = tkInteger) then begin
// Asignar el valor...
if (PInfo^.PropType^.Name = 'TColor') then begin
SetOrdProp(AObj, PInfo, StringToColor(Value));
end
else if (PInfo^.PropType^.Name = 'TCursor') then begin
SetOrdProp(AObj, PInfo, StringToCursor(Value));
end
else begin
SetOrdProp(AObj, PInfo, StrToInt(Value));
end;
end
else if (PInfo^.Proptype^.Kind = tkEnumeration) then begin
// Bloque de proteccion
try
if (PInfo^.PropType^ = TypeInfo(System.Boolean)) then begin
SetOrdProp(AObj, PInfo, StrToInt(Value));
end
else begin
SetOrdProp(AObj, PInfo, StrToInt(Value));
end;
except
raise;;
end;
end
else begin
Result := False;
end;
end
else begin
// No se ha encontrado la propiedad con ese nombre
Result := False;
end;
end;


Para usarlo puedes utilizar:


SetPropAsString(Edit1, 'Color', 'clRed');
SetPropAsString(Label1, 'Color', 'clRed');
...
// Añade al uses TypInfo (D6)

edalmasso
14-11-2005, 21:10:00
Probe el código y funciona perfectamente para componentes pero lo necesito para objetos creados de clases hechas por mi.

Ejemplo:
Teniendo las siguientes clases
TPaciente = Class
Nombre : String;
end;

TMate = Class
TieneBombilla : boolean;
end;

Necesito algo asi:
function AsignarPropiedad(pObjeto : TObject; pPropiedad: String; pValor:TObject);
begin
pObjeto.pPropiedad := pValor; //eso como se hace????
end;


y correrlo de la siguiente forma:
begin
Mate := TMate.Create; //para mate
AsignarPropiedad(Mate, 'TieneBombilla', 0);

Pacietne := TPaciente.Create;
AsignarPropiedad(Paciente, 'Nombre', 'Pablito');
end;

Muchas gracias y los felicito por la calidad del soporte y la calidad de las respuestas.
Saludos!:rolleyes:

jachguate
14-11-2005, 21:44:22
Hola.

¿Notas alguna diferencia entre el código escrito por vos y el escrito por Neftali?

Esto se debe al uso de etiquetas, [code], [delphi], [sql], disponibles acá en el club. Te invito a leer sobre estas etiquetas aqui, puesto que su uso es obligatorio para publicar trozos de código.

Hasta luego.

;)

Te invito a usarlas.

Hasta luego.

;)