Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-06-2003
Igna Igna is offline
Miembro
 
Registrado: jun 2003
Posts: 27
Poder: 0
Igna Va por buen camino
TCollection

Hola a todos.

Intentaré explicar mi duda de forma sencilla...Tengo un componente desarrollado por mi, descendiente de TStringGrid. Este componente tiene una propiedad de tipo TCollection. Lo que quiero hacer es que cuando se añada un nuevo item a la "coleción", se añada una nueva fila a mi componente (como hace el TDBGrid con las columns). Supongo que tendré que generar un evento cuando añada un nuevo item, y en el código del evento sumar una línea a mi componente, pero algo estoy haciento mal, por que me da errores.

Os pongo parte del código por si os aclara algo:

TNuevoUsuario = procedure (Sender: TObject) of object;


TUsuarios = class(TCollection)
private
FNuevoUsuario: TNuevoUSuario;
public
constructor Create(Owner : TPersistent);
destructor Destroy; override;
Function Add:TUsuariosItem;
function Insert(Index: Integer): TUsuariosItem;
property Items[Index: Integer]: TUsuariosItem
read GetItem
write SetItem;
property NuevoUsuario: TNuevoUsuario read FNuevoUsuario write FNuevoUsuario;

TOcupacion = class(TStringGrid)
private
FUsuarios: TUsuarios;
procedure NuevoUsuarioEvento(sender:TObject);

..............................

Function TUsuarios.Add:TUsuariosItem;
begin
result:=TUsuariosItem(Inherited Add);
if Assigned(NuevoUsuario) then
NuevoUsuario(Self);
end;

constructor TOcupacion.Create(AOwner: TComponent);
begin
Inherited;
FUsuarios := TUsuarios.Create(AOwner);
FUsuarios.NuevoUsuario := NuevoUsuarioEvento;
end;

procedure TOcupacion.NuevoUsuarioEvento(Sender: TObject);
begin
RowCount:=RowCount+1;
end;



Agradecería cualquier orientación sobre el tema.

Un saludo.
Responder Con Cita
  #2  
Antiguo 24-06-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola Igna, aquí van una serie de orientaciones:

Es recomendable que TUsuarios descienda de un TOwnedCollection en vez de un TCollection. El TOwnedCollection simplemente es un TCollection que implementa el método GetOwner (si mal no recuerdo), de esta forma Delphi puede mostrarlo desde el Object Inspector.

Otra cosa, el tipo de evento TNuevoUsuario es idéntico en su declaración al evento TNotifyEvent, así que lo puedes evitar.

El problema que sucede con el método Add (también con el Insert) de la clase TUsuarios es que devuelve un TUsuarioItem, no un TCollectionItem como en la clase TCollection, por eso es obligadamente un método no heredado. ¿Qué sucede? Que Delphi, cuando insertas un nuevo Item desde el IDE no llama a esa método Add sino al método Add de TCollection, y por lo tanto no se ejecuta el método Add que tú defines, consecuentemente tampoco se ejecuta el evento NuevoUsuario.

Otra cosa: cuando creas el objeto TUsuarios, debes pasarle como Owner tu componente (TOcupacion), es decir Self, no el Owner de TOcupacion (que normalmente será un Form o un Panel), y además hay que pasarle como parámetro la clase de los Items que va a manejar (TUsuarioItem); ésta es la forma que tienen los TCollection de saber qué Items deben crear cuando se llama a Add o Insert:

FUsuarios := TUsuarios.Create(Self, TUsuarioItem);

(te escribo de memoria, aquí no tengo el Delphi, pero creo que ese es el orden de los parámetros para un TOwnedCollection)

en vez de

FUsuarios := TUsuarios.Create(AOwner);

La solución que vengo empleando cuando uso colecciones y quiero hacer cosas de ese tipo que tú comentas, consiste en redefinir el método Create del TUsuarioItem, y ahí es donde se realiza el trabajo (ese método sabes seguro que se va a disparar). Sería una cosa como esta:

constructor TUsuarioItem.Create (ACollection: TCollection);
begin
inherited Create (ACollection);
if Assigned(ACollection) AND (ACollection is TUsuarios) then
TUsuarios(ACollection).NuevoUsuario(Self);
end;

Comprobamos que ACollection no es nil y que es del tipo TUsuarios (quizás demasiadas comprobaciones) y lanzamos el evento deseado.

Otra opción sería que la clase TUsuarios no tuviera definido ningún evento. Aún así podríamos lanzar el método NuevoUsuario de la clase TOcupacion, puesto que el TUsuarioItem tiene acceso al Owner del TUsuario que debe ser del tipo TOcupacion, algo así:

if Assigned(ACollection) AND Assigned(ACollection.Owner) AND
(ACollection.Owner is TOcupacion) then
TOcupacion(ACollection.Owner).NuevoUsuario(Self);

Como ves, son varias formas de hacerlo. Si te surge alguna duda ya nos dirás, creo que esto te debe funcionar.
__________________
Guía de Estilo
Responder Con Cita
  #3  
Antiguo 24-06-2003
Igna Igna is offline
Miembro
 
Registrado: jun 2003
Posts: 27
Poder: 0
Igna Va por buen camino
Muchas gracias andres1569. Ahora me funciona perfecto.

Supongo que ahora me surgirán otros problemas (intentaré resolverlos antes de "molestaros" de nuevo). El componente que estoy creando es para ver la ocupación de los empleados leyendo los datos de los calendarios del outlook (creía que iba a ser más difícil, pero por ahora no va mal del todo la cosa).

Gracias de nuevo por tu rápida y extensa respuesta.

Un saludo.
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


La franja horaria es GMT +2. Ahora son las 13:32:00.


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