Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
recorrer lista de controles hijos.

Hola a todos,

Tengo una duda. Habitualmente, cuando diseño una aplicación (suelen ser todas más o menos parecidas, de gestión, consultas a bases de datos y cosas así, no demasiado rebuscadas), suelo poner el formulario principal maximizado, y después ir construyendo las distintas secciones del programa en distintos frames.

Cuando se selecciona una opción del menú se esconden todos los frames y despues se hace visible el que corresponda. Esto me obliga a que en todos mis programas tengo que hacer una rutina de esconder_frames que es una pesadez:

frame1.hide;
frame2.hide;
.....
frame95.hide;

Cuando selecciono una opción del menu, hago:
escodertodos;
frameN.init;

y en el frameN he definido el procedimiento init, donde hago un self.show;
A parte, en ese procedimiento de inicio, que utilizo para cargar datos, si hacen falta, cargar opciones de combos, cosas así, suelo incluir también una rutina de limpiar_campos, donde tengo que recorrer todos los controles del frame haciendo:
Edit1.text := '';
Edit2.text := '';
...
Edit99.text := '';

Es muy repetitivo y una pesadez. Me preguntaba si no habrá alguna forma de otorgar un valor a una propiedad de un conjunto de controles del mismo tipo.En realidad me bastaría con saber como recorrer una lista de controles hijos.. así para hacer el esconder todos, podría ir recorriendo la lista desde el formularioprincipal y hacer

if tipocontrol(control)=Tframe then
control.hide

o en el init de cada frame, poder hacer

if tipocontrol(control)=Tedit then
control.text := '';

Espero haberme explicado bien. En realidad se puede resumir todo esto en que me gustaría saber si existe una forma de poder ir recorriendo todos los controles que están dentro de un formulario, un frame, o un groupbox.. sin tener que recurrir al nombre de cada control.

Gracias y un saludo.
Responder Con Cita
  #2  
Antiguo 05-04-2007
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Prueba con esto para los edits

Código Delphi [-]
Procedure Limpiar(Frame:Tframe);
var
  I:Integer;
begin
  For I:=Frame.ComponentCount-1 downto 0 then
    if Components[i] is TEdit then
      Tedit(Component[i]).Clear;
end;
Lo mismo lo puedes aplicar para los Frames.
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #3  
Antiguo 05-04-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Realmente no tienes que esconder todos los frames cada vez, sino únicamente el que estuviere visible al momento de activar otro. Una solución podrías ser la de llevar una variable

Código Delphi [-]
FrameActivo: TFrame;

que apunte al frame activo. Cuando muestres un frame pondrías algo como:

Código Delphi [-]
FrameActivo.Hide;
FrameAMostrar.Show;
FrameActivo := FrameAMostrar;

// Saludos
Responder Con Cita
  #4  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
solución parcial.. una vuelta de tuerca más..

Encontré la solución haciendo lo siguiente:

Código:
procedure TFrameClientes.limpiar_detalle;
var
   i : integer;
begin
   for i:=0 to FormPrincipal.FrameClientes1.ComponentCount-1 do
      begin
         if (FormPrincipal.FrameClientes1.Components[i] is TEdit) then
            Tedit(FormPrincipal.FrameClientes1.Components[i]).text := '';
         if (FormPrincipal.FrameClientes1.Components[i] is TCheckBox) then
            TcheckBox(FormPrincipal.FrameClientes1.Components[i]).checked := false;
         if (FormPrincipal.FrameClientes1.Components[i] is TMemo) then
            TMemo(FormPrincipal.FrameClientes1.Components[i]).text := '';
         if (FormPrincipal.FrameClientes1.Components[i] is TComboBox) then
            begin
               TComboBox(FormPrincipal.FrameClientes1.Components[i]).text := '';
               TComboBox(FormPrincipal.FrameClientes1.Components[i]).itemindex := -1;
            end;
      end;
end;
Ahora quedaría otro reto.. y es hacer este procedimiento más general aún...
Que no lo tenga que escribir para cada frame.. sino que el frame fuera un parámetro y poder llamar al procedimiento como:

limpiar_detalle(FrameClientes1);

¿Alguien sabe cómo?

Salu2
Responder Con Cita
  #5  
Antiguo 05-04-2007
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Con el código que te di mas arriba, lo puedes hacer. El procedimiento capta un parametro de la clase TFrame.
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #6  
Antiguo 05-04-2007
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Una pregunta,...Por qué no destruyes el Frame? antes de llamar al próximo.
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #7  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
lo encontré!!

Al final resultó ser una chorradilla...

Creé un fichero (suelo crearlo para meter en él todos los procedimientos "reutilizables") llamado unitFunciones que de momento solo contiene ésto:
Código:
unit UnitFunciones;

interface

uses Forms, StdCtrls;

procedure limpiar_detalle(frame: Tframe);

implementation

procedure limpiar_detalle(frame: Tframe);
var
   i : integer;
begin
   for i:=0 to frame.ComponentCount-1 do
      begin
         if (frame.Components[i] is TEdit) then
            Tedit(frame.Components[i]).text := '';
         if (frame.Components[i] is TCheckBox) then
            TcheckBox(frame.Components[i]).checked := false;
         if (frame.Components[i] is TMemo) then
            TMemo(frame.Components[i]).text := '';
         if (frame.Components[i] is TComboBox) then
            begin
               TComboBox(frame.Components[i]).text := '';
               TComboBox(frame.Components[i]).itemindex := -1;
            end;
      end;
end;

La llamada la hago desde el init de cada uno de los frames, haciendo:

Código:
limpiar_detalle(FormPrincipal.FrameClientes1);
y voilá...

Si me hubiera puesto a investigar esto antes.. cuántas horas de trabajo me había ahorrado... El ultimo programa que hice tenía unos 20 frames, y limpiaba los campos uno a uno!!!.. no se cuantas líneas de código.. pero una burrada.. bueno, de los errores se aprende.

Gracias a todos.
Responder Con Cita
  #8  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
Cita:
Empezado por vtdeleon
Con el código que te di mas arriba, lo puedes hacer. El procedimiento capta un parametro de la clase TFrame.
Vaya... no me fijé en que usabas el frame como parámetro.... lo probé por mi cuenta y funcionó.. de todos modos, gracias.

Salu2
Responder Con Cita
  #9  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
Cita:
Empezado por vtdeleon
Una pregunta,...Por qué no destruyes el Frame? antes de llamar al próximo.
Porque no siempre limpio todos los campos del frame cada vez que entro. Depende de si llamo a init con algún parámetro o no. En ocasiones, interesa que al volver al frame que dejaste, mantenga el estado en el que estaba.

Salu2
Responder Con Cita
  #10  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
Joer.. Román.. como leches no he caido antes!!!.. si es que aún soy muy novato... en fin, muchas gracias de nuevo (utilizaré una variable de FrameActivo).

Nota: No os cuento la porrada de veces que he escrito un procedimiento para esconder todos los frames, porque me da vergüenza.

Saludos y gracias.
Responder Con Cita
  #11  
Antiguo 05-04-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Ya puestos a trabajar de la forma de roman, se podría hacer algo más automático:

Código Delphi [-]

 TForm1 = class(TForm)

private
   FFrameActivo : TFrame;
  procedure SetFrameActivo(const Value:TFrame);
public
  FrameActivo :TFrame read FFrameActivo write SetFrameActivo;
...

procedure TFrom1.SetFrameActivo(const Value:TFrame);
begin
  if Assigned(FFrameActivo) and (FFrameActivo <> Value) then
  begin 
    FFrameActivo.Hide;
  end;
  FFrameActivo := VAlue;
  FFrameActivo.Show;
end;

Con este rollo, a partir de ahora solo tienes que hacer:
Código Delphi [-]
  FrameActivo := frame1;
y listo, se oculta el que se estaba viendo y se muestra el nuevo.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 05-04-2007 a las 12:40:03.
Responder Con Cita
  #12  
Antiguo 05-04-2007
Byfed Byfed is offline
Miembro
 
Registrado: oct 2006
Posts: 18
Poder: 0
Byfed Va por buen camino
Hola Lepe,

Gracias por tu respuesta, pero.. no es enrevesar demasiado las cosas?? No alcanzo a ver la ventaja de lo que propones.. aunque seguramente es porque no tengo conocimientos suficientes.

Aprovecho para ampliar mis horizontes y preguntarte por el código siguiente que has puesto en tu respuesta:

Código:
public
 FrameActivo :TFrame read FFrameActivo write SetFrameActivo;
Eso de "read" y "write" qué significa y para qué sirve?

Gracias de nuevo y un saludo.
Responder Con Cita
  #13  
Antiguo 05-04-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Me equivoqué en esa línea, debería decir:
Código Delphi [-]
property FrameActivo :TFrame read FFrameActivo write SetFrameActivo;

Eso significa que cuando vamos a leer (read) la propiedad FrameActivo, en realidad se lee la variable FFrameActivo, típico en este caso:
Código Delphi [-]
var r:TFrame;
begin
  r := FrameActivo;
end

Y cuando se va a escribir (write) en esa variable, Ejemplo:
Código Delphi [-]
FrameActivo := Frame1;
Se ejecutará el procedimiento SetFrameActivo, con lo cual, podemos realizar otras operaciones. Además, como ese procedimiento lleva un parámetro, podemos saber si FFrameActivo ya tenía asignado el Frame1, el Frame2, o cualquier otro.

En el código delphi anterior, el parámetro "Value" será el valor que queremos asignar, es decir "Frame1".

Fíjate que antes de mi mensaje, tú tendrías que hacer lo dicho por roman, 3 líneas de código:
Código Delphi [-]
  FrameActivo.Hide;
  FrameAMostrar.Show;
  FrameActivo := FrameAMostrar;

A partir de ahora, es sólo una línea de código:
Código Delphi [-]
  FrameActivo := Frame1;

Mira cualquier unidad de delphi con clases, y verás que trabaja así internamente, es decir, no estoy inventando nada nuevo .

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Crear Procesos Hijos ygkw API de Windows 3 06-07-2006 20:07:47
Formulario MDI e Hijos chux OOP 7 07-12-2005 21:19:14
multiples hijos en un TTreeView bustio OOP 1 23-11-2005 09:42:03
Forms Hijos djj OOP 9 31-10-2004 02:16:27
...14 hijos... Jure Humor 0 18-08-2004 00:55:03


La franja horaria es GMT +2. Ahora son las 15:22:07.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi