RaiseEvent from a class contained in a 2nd class collection?

  • Thread starter Thread starter Andrew
  • Start date Start date
A

Andrew

I have two objects: cField and cSink. There are many Fields and
pointers to these are stored in a collection within the cSink objects.
When a change is made in the cField object I need it to trigger an
event in the cSink object. I have this almost correct but although
the fields are being stored in the collection okay the event is only
triggered for the last field that was added. I suspect this has
something to do with my WithEvents declaration in cSink but I'm not
sure what to try next.

My code looks like:

*** cField ***
' Declarations
Public Event FieldStatusChange()
' Routines
Sub DoSomething()
...
RaiseEvent FieldStatusChange
End Sub

*** cSink ***
' Declarations
Private WithEvents AllocatedField As cField
Private p_colAllocatedFields As Collection
'Routines
Public Sub AllocateField(objNewField As cField)
Set AllocatedField = objNewField
'Store a pointer to the new field object in our collection
p_colAllocatedFields.Add AllocatedField
End Sub
Private Sub AllocatedField_FieldStatusChange()
msgbox "Event was triggered"
End Sub


If anyone can help it would be greatly appreciated.

Thanks,
Andrew
 
Maybe a Christmas Eve posting was a bit optimistic...
The only way I have managed to get this to work is to create a third
class called CustomEvents and put the WithEvents declaration in there.
That way I create a new instance of the CustomEvents class for every
field. This is quite a bit messier than what I set out to do. Is
there no way to set a new reference to the same WithEvents declaration
and store it in a collection??

Any help would be much appreciated - I can see that raising and
trapping events could be really useful for me if i can just get my
head around them.

Thanks again,
Andrew
 
If I understand correctly, you want to notify the parent class that
something happened in the child class.

The approach I use (idea pinched from elsewhere) is to use a third
class, CMessenger, whose sole purpose is to convey messages from child
to parent. This is different from your approach in that the child does
not raise the event, rather CMessenger does. The parent persists a
single Withevents instance of CMessenger and each child is passed a
pointer. To notify the parent, the child calls a CMessenger method
which raises an event which in turn notifies the parent. It's a lot
less complicated than it sounds.

Here's a quick example. Create a new userform called Userform1 with
three textboxes called TextBox1, TextBox2 and TextBox3 respectively.
Create three new class modules called CParent, CChild and CMessenger
respectively. Paste the following code into the relevant code module:

'<Code:Userform1>--------
Option Explicit

Private m_oParent As CParent

Private Sub UserForm_Activate()
Set m_oParent = New CParent
With m_oParent
.NewChild TextBox1
.NewChild TextBox2
.NewChild TextBox3
End With
End Sub
'</Code:Userform1>--------

'<Code:CParent>--------
Option Explicit

Private WithEvents m_oMessenger As CMessenger
Private m_colChildren As Collection

Private Sub Class_Initialize()
Set m_oMessenger = New CMessenger
Set m_colChildren = New Collection
End Sub

Public Function NewChild(ByVal MSFormsTextBox As MSForms.TextBox) As
Boolean
Dim oChild As CChild
Set oChild = New CChild
oChild.Init MSFormsTextBox, m_oMessenger
m_colChildren.Add oChild
End Function

Private Sub m_oMessenger_DoublClick(ByVal MSFormsTextBox As
MSForms.TextBox)
MsgBox "Double click in " & MSFormsTextBox.Name
End Sub
'</Code:CParent>--------

'<Code:CChild>--------
Option Explicit

Private WithEvents m_oTextbox As MSForms.TextBox
Private m_oMessenger As CMessenger

Friend Function Init(ByVal MSFormsTextBox As MSForms.TextBox, _
ByVal Messenger As CMessenger) As Boolean
Set m_oTextbox = MSFormsTextBox
Set m_oMessenger = Messenger
End Function

Private Sub m_oTextbox_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
m_oMessenger.SendMessage odwDoublClick, m_oTextbox
End Sub
'</Code:CChild>--------

'<Code:CMessenger>--------
Option Explicit

Public Enum odwMessageTypeEnum
odwDoublClick = 1
End Enum

Public Event DoublClick(ByVal MSFormsTextBox As MSForms.TextBox)

Public Function SendMessage(ByVal MessageType As odwMessageTypeEnum, _
ByVal MSFormsTextBox As MSForms.TextBox)
As Boolean
Select Case MessageType
Case odwDoublClick
RaiseEvent DoublClick(MSFormsTextBox)
End Select
End Function
'</Code:CMessenger>--------

Run the userform and double click in one of the textboxes (set
relevant breakpoints to see what's going on).

--
 
Back
Top