PDA

Ver la Versión Completa : Busqueda de Componente y propiedades


rruffino
28-09-2017, 15:49:39
Hola gente, buen día...
Tengo en el formulario un panel con varios checkbox, y para no escribir mucho código, pensaba en localizarlos a traves del nombre de los mismos y ahi cambiar algunas propiedades, principalmente la propiedad Checked...
Buscando he encontrado varios ejemplos y he implementado el que presento a continuación..

var
Butaca: TComponent;
nombre: string;
i: integer;
begin
for i:=0 to 10 do
begin
nombre:='F1_' ;
butaca:=FindComponent(nombre);
if Assigned(butaca)then
begin
if (butaca is TCheckBox) then
TCheckBox(butaca).Checked:=true;
end;
end;

El problema que tengo es que cuando verifica si esta asignado, la condición da falso, por lo que no puedo cambiar el estado del Checked...si por el contrario saco la condición donde verifica si está asignado, al cambiar la propiedad de Checked da error y no lo hace, error como si el comprobante no estuviese referenciado.. a mi entender es como si el FindComponent no encuentra el componente...
Desde ya agradezco cualquier comentario y/o sugerencia.
Saludos!!!

ElDioni
28-09-2017, 16:01:44
Hola, tengo dudas.

¿cuando se ejecuta ese código?
¿para que sirve el for?

Por lo que veo le asignas directamente el nombre del componente que quieres buscar, por lo que entiendo que ya sabes que ese nombre que pasas corresponde a un checkbox, no te haría falta comprobarlo después.

También puedes probar con:


TCheckbox(FindComponent('F1_')).Checked:=true;


Así te evitarías tener que crear el TComponent y asignarlo.

Saludos.

rruffino
28-09-2017, 16:04:20
Bueno, quizas el sueño me juega mala pasada....

Butaca:TComponent.Crate(self);


la solución al problema..... ahora tengo en una tabla los nombres a buscar y ahi si no me los encuentra

nombre:=Tabla.FieldValues['nombre'];


Ahi si ya no entiendo por que no lo encuentra....

rruffino
28-09-2017, 16:07:44
Gracias ElDioni por la respuesta, en realidad el nombre lo compongo de la siguiente manera:

for i:=0 to 10 do
begin
nombre:='F1_' ;
butaca:=FindComponent(nombre + InttoStr(i));
...
...


para que me genere y busque los 10 nombres

ecfisa
28-09-2017, 17:40:30
Hola.

Sólo un detalle, en ese caso la comprobación:

if Assigned(butaca)then // <-
begin
if (butaca is TCheckBox) then

es innecesaria.

Dado que el operador is devuelve True si el objeto evaluado pertenece a la clase o es descendiente de ella y False de otro modo (incluyendo también a nil), podes escribir:

...
var
i: Integer;
Butaca: TComponent;
begin
for i := 0 to ComponentCount-1 do
begin
Butaca := FindComponent('F1_'+IntToStr(i+1)); // +1 si los nombres fuesen: F1_1, ..., F1_10
if Butaca is TCheckBox then
TCheckBox(Butaca).Checked := True;
end;
end;


Lo que no alcanzo a comprender bién es la mecánica de la obtención del nombre desde la tabla, pero en principio podrías hacer uso del método Locate (http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_Locate).

Saludos :)

Soa Pelaez
28-09-2017, 17:47:29
Otra manera podría ser.

Tal vez esta entrada pueda ayudar: "Modificar propiedades de controles en ejecución utilizando RTTI". (http://neftali.clubdelphi.com/?p=53)

La ventaja de hacerlo con RTTI es que podría llamar a esta función:


// Otros ejemplos
SetPropAsString(Components[i], 'Left', '10');
SetPropAsString(Components[i], 'Color', 'clRed');


Sin preocuparte del Tipo de control (TEdit, TCheckbox,...). Si tiene la propiedad y se llama así la cambiará.

ecfisa
28-09-2017, 18:53:58
Hola.

Como menciona Soa Pelaez, también se puede usar RTTI. Con la salvedad que debe verificarse si la propiedad sobre la que se va a aplicar el valor existe en el componente actual para evitar excepciones.

...
implementation

uses TypInfo;

procedure TForm1.CheckOnOff(const aChecked: Boolean);
var
i: Integer;
begin
for i := 0 to ComponentCount-1 do
if Assigned(GetPropInfo(Components[i].ClassInfo, 'Checked')) then
SetOrdProp(Components[i], 'Checked', Integer(aChecked) );
end;

// Ejemplo de uso:
procedure TForm1.Button1Click(Sender: TObject);
begin
CheckOnOff(not CheckBox1.Checked);
end;


Saludos :)