|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
event propagationcollection 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. Code follows... ------------------------------------------------------ 'CEnclosure ------------------------------------------------------ Option Explicit Public Event GotDirty() 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 ------------------------------------------------------ 'CEnclosures ------------------------------------------------------ Option Explicit Implements IUnknown Public Event GotDirty() Private mCol As Collection Private WithEvents newENC As CEnclosure Public Property Get NewEnum() As IUnknown Set NewEnum = mCol.[_NewEnum] End Property Public Property Get Item(IndexKey As Variant) As CEnclosure Set Item = mCol(IndexKey) End Property Public Property Get Count() As Long Count = mCol.Count End Property Public Sub Remove(IndexKey As Variant) mCol.Remove IndexKey RaiseEvent GotDirty End Sub Public Function Add(Index As Integer, Reference As String) As CEnclosure Set newENC = New CEnclosure newENC.Reference = Reference If mCol.Count = 0 Then mCol.Add newENC ElseIf Index > mCol.Count Then mCol.Add newENC, , , mCol.Count Else mCol.Add newENC, , Index End If RaiseEvent GotDirty Set Add = newENC Set newENC = Nothing End Function Private Sub Class_Initialize() Set mCol = New Collection End Sub Private Sub Class_Terminate() Set mCol = Nothing End Sub Private Sub newENC_GotDirty() RaiseEvent GotDirty End Sub ------------------------------------------------------ 'CWorkflow ------------------------------------------------------ Option Explicit Public Event GotDirty() Private WithEvents mENC As CEnclosures Private mInfo As String 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 ------------------------------------------------------ 'FORM ------------------------------------------------------ Option Explicit Dim WithEvents w As CWorkflow 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 "thegios" <theg***@discussions.microsoft.com> wrote It is missing because you do not have anyone listening when the event is raised.> 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. <...> > 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. > Public Function Add(Index As Integer, Reference As String) As CEnclosure < ... > > Set Add = newENC Note here that you set newENC to Nothing, so it no longer will be listening> Set newENC = Nothing > End Function for events. Typically, if you want to raise an event from many child objects to a single parent object, you'd do that using a third object that you can pass to all the child objects. Each child then has a reference to the same object delegated to raising events, and the parent only needs to listen for events from that one delegated object. A simple example follows: Uses 4 modules: TYPE NAME Form Form1 Class Parent Class Child Class Delegate ' [ Form1 ] Option Explicit Private WithEvents Mom As Parent Private Sub Form_Load() Set Mom = New Parent Dim Sue As Child Dim Ted As Child Dim Pat As Child Set Sue = Mom.Create("Sue", 12) Set Ted = Mom.Create("Ted", 10) Set Pat = New Child Pat.Name = "Pat" Pat.Age = 8 Mom.Add Pat ' Event raised from parent Pat.Name = "Patty" ' Event raised from child Sue.Age = 13 ' Event raised from child End Sub Private Sub Mom_Shouting(Kid As Child, Msg As String) Debug.Print Kid.Name, Msg End Sub ' [ Parent ] Private Kids As New Collection Private WithEvents ChildControl As Delegate Public Event Shouting(Kid As Child, Msg As String) Public Sub Add(Kid As Child) Kids.Add Kid Set Kid.Control = ChildControl RaiseEvent Shouting(Kid, "Added to collection.") End Sub Public Function Create(Name As String, Age As Long) As Child Set Create = New Child Create.Name = Name Create.Age = Age Set Create.Control = ChildControl End Function Private Sub ChildControl_Shouting(Kid As Child, Msg As String) RaiseEvent Shouting(Kid, Msg) End Sub Private Sub Class_Initialize() Set ChildControl = New Delegate End Sub ' [ Child ] Public Control As Delegate Private mName As String Private mAge As Long Public Property Get Name() As String Name = mName End Property Public Property Let Name(ByVal NewName As String) If NewName <> mName Then mName = NewName ReportBack "Name change." End If End Property Public Property Get Age() As Long Age = mAge End Property Public Property Let Age(ByVal NewAge As Long) If NewAge <> mAge Then mAge = NewAge ReportBack "Age change." End If End Property Private Sub ReportBack(Msg As String) If Not Me.Control Is Nothing Then Me.Control.Shout Me, Msg End If End Sub ' [ Delegate ] Public Event Shouting(Kid As Child, Msg As String) Public Sub Shout(Kid As Child, Msg As String) RaiseEvent Shouting(Kid, Msg) End Sub |
|||||||||||||||||||||||