![]() |
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. |
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. |
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. |
La franja horaria es GMT +2. Ahora son las 23:46:42. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi