I have a CWorkflow class, containing a Cenclosures class, which is a collection class of CEnclosure items.
CEnclosure fires a GotDirty event when an enclosure's property is changed.
Cenclosures catches the CEnclosure.GotDirty event and fires another GotDirty event; it fires a GotDirty event
even when a new enclosure is added or an existing one is deleted.
Cworkflow catches the CEnclosures.GotDirty event and fires another GotDirty event; it fires a GotDirty event
even when a workflow's property is cahnged.
My main form catches the CWorkflow.GotDirty event and displays a message box.
This menas that in the form, if I create a workflow object, I change one of its property, then I add an
enclosure and I change one of the enclosure's property, 4 message boxes should appear: one when changing the
workflow's property; two when adding an enclosure (because I create a new enclosure and set its property and
ebcause the collection class is changed) and one when changing a property of the just added enclosure.
The problem is hat I get only 3 message boxes, because the last one is missing, that is no event if fired/caught
when changing a property of the just added enclosure.
Private mReference As String
Public Property Let Reference(Value As String)
mReference = Value
RaiseEvent GotDirty
End Property
Public Property Get Reference() As String
Reference = mReference
End Property
Private Sub Class_Initialize()
mReference = ""
End Sub
Public Property Let Info(Value As String)
mInfo = Value
RaiseEvent GotDirty
End Property
Public Property Get Info() As String
Info = mInfo
End Property
Public Property Get Enclosures() As CEnclosures
Set Enclosures = mENC
End Property
Private Sub Class_Initialize()
mInfo = ""
Set mENC = New CEnclosures
End Sub
Private Sub Class_Terminate()
Set mENC = Nothing
End Sub
Private Sub mENC_GotDirty()
RaiseEvent GotDirty
End Sub
Private Sub Command1_Click()
Dim el As CEnclosures
Dim e As CEnclosure
Set w = New CWorkflow
w.Info = "Info" 'Here 1 message box is displayed since one event is fired from CWorkflow
Set el = w.Enclosures
Set e = el.Add(3, "Enclosur") 'Here 2 message boxes are displayed
'since 2 events are fired: one from CEnclosure and
'one from CEnclosures
e.Reference = "Enclosure" 'Here 1 message box should be displayed but it is not
'because no event is fired
End Sub
Private Sub w_GotDirty()
MsgBox "GotDirty"
End Sub
09-19-2005, 02:08 PM
mstraf
I believe this is what is happening.
In CEnclosures, you declare a CEnclosure with events, and you add it to the collection. But then you set it to nothing, so at this points the object still exists because it is still referenced by the Collection, but has lost the Sync interface that allows the event to be fired.
In situations like this (it is the same in an array of objects, not only a Collection) one solution is to add an extra class that raises the event, and pass it around:
CEventSync code:
Public event MyEvent()
public sub RaiseMyEvent()
raiseevent MyEvent
end sub
Create one instance withevents of this class in CEnclosures:
private withevents m_c as CEventSync
private sub m_c_MyEvent()
raiseevent GotDirty
end sub
and pass this class to each of the created CEnclosure objects. In CEnclosure, keep a reference of this class in a private variable then, instead of raising the event, call the RaiseMyEvent method of this new class.
This is just one method, and it is the one I prefer because it does not create any circular reference and does not need any global object.