Raising events from collection member objects?!?! 
Author Message
 Raising events from collection member objects?!?!

I recently posted a question about how to raise an event from an object
referenced by a collection.  The response I got was:

Have the objects stored in the collection raise an event.  This event would
include the object's key, or index in the event's argument list.  You'd have
to store that in an object property.  Declare the objects in the "client"
(or event sink) object/form "With Events".  Code an event handler for this
in the client/sink object.  That event handler would use the key or index to
differentiate the collections constituent objects.

This is helpful, but the problem with this solution is that the event only
gets raised when an object variable (other than the collection) that was
declared "WithEvents" is referring to the object that raises the event at
the time the event is raised.  This is obviously a problem because I can't
predict which object will raise an event at any given time, and neither can
I reasonably maintain individual object variables for each of the n objects
I've created.  That's the purpose of the collection; to maintain references
to an indeterminate number of objects.  So, the problem remains:  If I
create n objects, add them to a collection, and maintain the collection as
my only reference to the objects created, is there any way to intercept
events raised by objects that are members of the collection.  Again, I want
the objects in the collection to raise events much the same way controls in
a control array raise events.  Also, I'm not stuck on using a collection; if
there's a way to do this using arrays or some other structure, I'd love to
hear about it.

Obviously I can't have this:

private withevents object_1 as class1
private withevents object_2 as class1
private withevents object_3 as class1
...
private withevents object_n as class1

Thanks for anyone's help with this.  Please respond even if you know this
cannot be done because it'll save me the time of wondering if there's a way
to do it.

Dave Clipsham
Bloomfield & Grossart, Inc.



Tue, 02 Jul 2002 03:00:00 GMT  
 Raising events from collection member objects?!?!
A different approach would be not to have events at all, but rather have a
public procedure in a module that is called from the class.  Your class
would need to have something like a strKey property that you set when adding
to your array or collection, and that strKey property is passed to the code
modules procedure as one of the arguements.

--
Bill McCarthy, MVP VB
Total Environment
www.TotalEnviro.com/PlatformVB


Quote:
> I recently posted a question about how to raise an event from an object
> referenced by a collection.  The response I got was:

> Have the objects stored in the collection raise an event.  This event
would
> include the object's key, or index in the event's argument list.  You'd
have
> to store that in an object property.  Declare the objects in the "client"
> (or event sink) object/form "With Events".  Code an event handler for this
> in the client/sink object.  That event handler would use the key or index
to
> differentiate the collections constituent objects.

> This is helpful, but the problem with this solution is that the event only
> gets raised when an object variable (other than the collection) that was
> declared "WithEvents" is referring to the object that raises the event at
> the time the event is raised.  This is obviously a problem because I can't
> predict which object will raise an event at any given time, and neither
can
> I reasonably maintain individual object variables for each of the n
objects
> I've created.  That's the purpose of the collection; to maintain
references
> to an indeterminate number of objects.  So, the problem remains:  If I
> create n objects, add them to a collection, and maintain the collection as
> my only reference to the objects created, is there any way to intercept
> events raised by objects that are members of the collection.  Again, I
want
> the objects in the collection to raise events much the same way controls
in
> a control array raise events.  Also, I'm not stuck on using a collection;
if
> there's a way to do this using arrays or some other structure, I'd love to
> hear about it.

> Obviously I can't have this:

> private withevents object_1 as class1
> private withevents object_2 as class1
> private withevents object_3 as class1
> ...
> private withevents object_n as class1

> Thanks for anyone's help with this.  Please respond even if you know this
> cannot be done because it'll save me the time of wondering if there's a
way
> to do it.

> Dave Clipsham
> Bloomfield & Grossart, Inc.




Wed, 03 Jul 2002 03:00:00 GMT  
 Raising events from collection member objects?!?!
You're right to want to use events from collections. All sophisticated
object models support them.

An approach that I've used is as follows:

-- First, use collection classes. Let's assume that your CCustomer object
owns a collection of orders. A variable of type COrders would be declared
WithEvents in the CCustomer object. The COrders collection would support the
standard collection methods and properties, including Add, Item (the
default), Count and Remove. In addition:

-- Add a friend method to the COrders collection class --
RaiseEvent(EventKey As Long, Item As Variant).   EventKey will identify
which event you'd like to raise, Item can either hold a reference to the
item raising the event, or the item's key. Use a select case to raise the
appropriate event.
-- Add a public event to the class for each event you'd like your individual
objects to support. If the items need to support a DataChanged event, for
example, add a public event to the collection: DataChanged(Item as Variant).
-- Add a friend property to the COrder object (the individual item in the
collection) that allows you to pass a reference to the parent collection
when the new COrder is added to it. Typically, I call this the Parent
property.
-- When new items are added to the COrders collection (in the COrders.Add
method) set the Parent property of the new COrder = me.
-- In the COrder, when you need to raise an event, just call
Parent.RaiseEvent, passing the correct EventKey and either a reference to
the COrder or its index.

Since the COrder holds a reference to COrders, be sure that when you want to
get rid of that object, you release the reference to COrders, otherwise
COrder's Class_Terminate will never fire and you'll get memory leaks. I'd
add a friend Destroy method to the COrder, which I call before setting the
reference to nothing. Also, add a Friend Destroy method to the collection,
which calls Destroy on the items before removing them.

In a recent project, where I was dealing with around 50 different
collections, I found it much easier to create a generic IEventMgr interface,
which was implemented in all the collections. That way, each child object's
Parent property was of type IEventMgr, not COrders or CItems or whatever,
and the code in the items could be copied without worrying about changing
the declarations.

Let me know if you'd like some examples.

David E. Hirshfield, MCSD


Quote:
> A different approach would be not to have events at all, but rather have a
> public procedure in a module that is called from the class.  Your class
> would need to have something like a strKey property that you set when
adding
> to your array or collection, and that strKey property is passed to the
code
> modules procedure as one of the arguements.

> --
> Bill McCarthy, MVP VB
> Total Environment
> www.TotalEnviro.com/PlatformVB



> > I recently posted a question about how to raise an event from an object
> > referenced by a collection.  The response I got was:

> > Have the objects stored in the collection raise an event.  This event
> would
> > include the object's key, or index in the event's argument list.  You'd
> have
> > to store that in an object property.  Declare the objects in the
"client"
> > (or event sink) object/form "With Events".  Code an event handler for
this
> > in the client/sink object.  That event handler would use the key or
index
> to
> > differentiate the collections constituent objects.

> > This is helpful, but the problem with this solution is that the event
only
> > gets raised when an object variable (other than the collection) that was
> > declared "WithEvents" is referring to the object that raises the event
at
> > the time the event is raised.  This is obviously a problem because I
can't
> > predict which object will raise an event at any given time, and neither
> can
> > I reasonably maintain individual object variables for each of the n
> objects
> > I've created.  That's the purpose of the collection; to maintain
> references
> > to an indeterminate number of objects.  So, the problem remains:  If I
> > create n objects, add them to a collection, and maintain the collection
as
> > my only reference to the objects created, is there any way to intercept
> > events raised by objects that are members of the collection.  Again, I
> want
> > the objects in the collection to raise events much the same way controls
> in
> > a control array raise events.  Also, I'm not stuck on using a
collection;
> if
> > there's a way to do this using arrays or some other structure, I'd love
to
> > hear about it.

> > Obviously I can't have this:

> > private withevents object_1 as class1
> > private withevents object_2 as class1
> > private withevents object_3 as class1
> > ...
> > private withevents object_n as class1

> > Thanks for anyone's help with this.  Please respond even if you know
this
> > cannot be done because it'll save me the time of wondering if there's a
> way
> > to do it.

> > Dave Clipsham
> > Bloomfield & Grossart, Inc.




Thu, 04 Jul 2002 03:00:00 GMT  
 Raising events from collection member objects?!?!
Dave
Here is the response I made to your previous post.

The WithEvents Statement will not work with a control array or object in a
collection. It requires a one to one relationship with an Object. If you
are going to have many objects in a collection a better method may be to
use callbacks. This way you can pass every class you create an interface to
call back into. So instead of raising and event it would just call a method
in the callback class. You could use the same object instance for all the
class objects in the collection.

Thanks
Brian Combs
Microsoft Developer Support for Visual Basic



Fri, 05 Jul 2002 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Raise event from Collection member??

2. Raising events from objects in a collection

3. Raising events from objects in a collection

4. Raising events from objects in a collection

5. Objects in Collection and Raise Events

6. Raising events from objects in a collection???

7. Raising events from objects in a collection???

8. Raising events from objects in a collection???

9. Raising events from objects in a collection???

10. Raising events from objects in a collection???

11. Raising events from objects in a collection???

12. Raising events from a class within a collection class

 

 
Powered by phpBB® Forum Software