PDA

Ver la Versión Completa : Como reutilizar un Form


dchaparro
27-05-2004, 03:18:01
Hola. Despues de haber buscado en los fors anteriores, no encontre una explicacion clara del asunto, o sea "Como reutilizar un form" ya sea en un mismo proyecto o en otro.
En todos lados leo que se puede reutilizar codigo, etc.., el problema para un principiante en Delphi (y en POO) es "como" hacerlo.
En particular, quiero reutilizar forms de altas, bajas y modificaciones de una Tabla, por que en cada proyecto que hago tengo que escribir mil veces el Evento OnClick del boton "Save" o "Cancel", para cada Tabla que edito.
La pregunta sería:
:confused: -como puedo crear un form con 2 botones: Save y Cancel, y usarlo (o reusarlo) para distintas tablas, agregando a mano Dbedits a los campos que quiero modificar o editar, o esto tambien se puede automatizar?
:confused: -Como lo uso en otro proyecto?

Desde ya, muchas gracias a todos.:)

jachguate
27-05-2004, 03:32:17
Hola.

Tenes muchas formas de reutilizar el código. La que yo prefiero es la herencia visual. Esto significa que definis un formulario, que puede tener controles, métodos y eventos. Luego, heredas nuevos formularios de este, que por supuesto ya tendrán el código, pero también el aspecto visual del primero. A estos podes añadir mas controles, métodos y eventos.

El libro "la cara oculta de delphi 4" que podes descargar totalmente gratis de la página de su autor, Ian Marteens (http://www.marteens.com) tiene una sección que te explica muy bien como explotar esta buena e ingeniosa implementación de OOP de borland.

Hay otras, como crear plantillas o utilizar el repositorio, pero como no las uso, pues no puedo hablar con propiedad de ellas.

Hasta luego.

;)

roman
27-05-2004, 03:40:31
Tenes muchas formas de reutilizar el código. La que yo prefiero es la herencia visual.

[...]

Hay otras, como crear plantillas o utilizar el repositorio


¿Pues que no la herencia visual se basa en el uso del repositorio?

// Saludos

jachguate
27-05-2004, 04:35:06
No necesariamente... podes heredar de cualquier form incluido en tu aplicación, aunque no esté en el repositorio...

Hasta luego.

;)

roman
27-05-2004, 05:30:38
Sí claro. Puedo heredar como con cualquier clase pero entonces ya no es visual a menos que manualmente cambie el ancestro y modifique el archivo dfm para cambiar object por inherited y esto es justamente lo que se hace automáticamente al usar el repositorio.

delphi.com.ar
27-05-2004, 15:42:53
Sí claro. Puedo heredar como con cualquier clase pero entonces ya no es visual a menos que manualmente cambie el ancestro y modifique el archivo dfm para cambiar object por inherited y esto es justamente lo que se hace automáticamente al usar el repositorio.Mmmmm....
File \ New \ (Nombre Proyecto) \ (Forma Padre)
Es herencia visual sin el uso del repositorio (a la larga es un repositorio de todos modos :))

roman
27-05-2004, 17:07:37
Mmmmm....
File \ New \ (Nombre Proyecto) \ (Forma Padre)
Es herencia visual sin el uso del repositorio (a la larga es un repositorio de todos modos :))

Pues sí, no es más que un repositorio, temporal si quieres, que se crea por proyecto abierto.

// Saludos

dchaparro
29-05-2004, 16:27:39
Para completar este hilo, tengo una pregunta mas que me surgio al heredar visualmente un form.
Primero cree dos forms: FormBase y FormEditBase, a estos le puse controles generales ya que de ellos voy a derivar los que realmente uso. El tema es que en FormBase quiero usar a FormEditBase, o sea hago lo siguiente:
procedure TFormBase.BtnNuevoClick(Sender: TObject);
begin
with TFormEditBase.Create(Application) do
try
ShowModal;
finally
Free;
etc.....

Ahora creo los forms que voy a utilizar, derivados de estos, que son: FormBase1 y FormEditBase1, pero cuando ejecuta BtnNuevoClick, me crea el form FormEditBase, y no el FormEditBase1 que es el que quiero usar !
La pregunta: qué código debería ir en BtnNuevoClick, para que use FormEditBase1 que es derivado de FormEditBase.
Graficamente se podria ilustrar para que quede mas claro de la siguiente manera:

Form usa a Form
FormBase ---> FormEditBase

FormBase1 ---> FormEditBase1
.......
.......
FormBaseN ---> FormEditBaseN

No se si estoy hablando en chino o si me entendieron algo :D , de todas maneras espero alguna luz sobre el asunto. Desde ya muchas gracias.

roman
29-05-2004, 17:12:24
procedure TFormBase.BtnNuevoClick(Sender: TObject);
begin
with TFormEditBase.Create(Application) do
try
ShowModal;
finally
Free;

{ etc }
end;



El problema aquí es que el formulario base no conoce cuáles serán los descendientes del formulario de edición.

Si te fijas, tu necesitarías poder tener

TFormEditBase1.Create(Application)
TFormEditBase2.Create(Application)
...
TFormEditBaseN.Create(Application)

según sea el caso. Pero la sentencia debe estar en el formulario base y no en cada descendiente. Entonces requerirías poner la clase del formulario de edición (TFormEdit1, TFormEdit2, etc.) en una variable que tomase uno de estos valores según corresponda. Pero si lees detenidamente verás que es un poco extraño: los valores de dicha variable serían tipos de datos de manera que, ¿cuál sería el tipo de datos de tal variable?

La respuesta es: referencias de clase. Las referencias de clase son tipos de datos cuyas variables (variables de este tipo) toman como valores otros tipos de datos.

Para usarla declara una para tu formulario base de edición:


type
TFormEditBase = class(TForm)
...
end;

TFormEditBaseClass = class of TFormEditBase;


Así, una variable de tipo TFormEditBaseClass podrá tomar como valores cualquier clase descendiente de TFormEditBase.

En la práctica lo que podrías hacer es agregar una de estas variables al formulario base:


type
TFormBase = class(TForm)
protected
FormEditClass: TFormEditBaseClass;
end;


y cambiar la creación del formulario de edición así:


procedure TFormBase.BtnNuevoClick(Sender: TObject);
begin
with FormEditClass.Create(Application) do
try
ShowModal;
finally
Free;

{ etc }
end;


Entonces, lo único que debes hacer es asignar el tipo correcto en el momento adecuado, por ejemplo, en el constructor de cada descendiente de TFormBase:


constructor TFormBaseN.Create(AOwner: TComponent);
begin
inherited;

FormEditClass := TFormEditBaseN;
end;


Para más información busca "Class references" en la ayuda de Delphi.

// Saludos

dchaparro
29-05-2004, 22:54:44
Sencillamente espectacular! Funciona a la perfeccion, y creo que gracias a Roman me voy a ahorrar mucho codigo a partir de ahora.
Todavia me cuesta ver bien cual es el funcionamiento de "Referencia de Clases", pero el que logre entenderla creo que da un gran paso en lo que es OOP en Delphi.
Gracias!