casading Events / AddHandlers

liptonIcedTea

Well-known member
Joined
Jan 18, 2007
Messages
89
Programming Experience
1-3
Hi,

A syntax question...

In my applicaiton, I've noticed that regularly, I have a child control that raises an event, which is handled by a calling class. This calling class, will often raise an event that calls their calling class etc.

I usually add a handler to the calling class's event, to point to a method, which the method then raises an event

Example.

AddHandler childControl.onClicked, addressof OnClicked

...

public sub OnClicked()
raiseevent On_Clicked()
end sub


Being lazy, I hate having to create a new method just to throw an event, I was wondering does VB allow you to create a handler that points straight to raising another event?

Something like this...

Addhandler childControl.onClicked, RaiseEvent On_Clicked()
 
Was this what you imagined? Here are three classes, level1-2-3, level1 contains an instance of level2, level2 contains an instance of level3. When level3 raises an event you want level1 to catch it without lots of bubble code in level2 class.
VB.NET:
Public Class frmTest
    Sub test()
        Dim l1 As New level1
        l1.l2.l3.raiser() 'whatever, just proves the point :)
    End Sub
End Class

Public Class level1
    Friend l2 As New level2
    Public Sub New()
        AddHandler l2.l3.e3, AddressOf handler
    End Sub
    Private Sub handler(ByVal sender As Object, ByVal e As EventArgs)
        MsgBox("level3.e3 event in level1")
    End Sub
End Class

Public Class level2
    Friend l3 As New level3
End Class

Public Class level3
    Public Event e3 As EventHandler
    Friend Sub raiser()
        RaiseEvent e3(Me, New EventArgs)
    End Sub
End Class
 
Hey John,

yeah that can work. It's probably the best solution - but i still don't really like it though.

Just because as a parent class, I shouldn't have to know about all the events that a child class may handle and the types of objects that a child class has and all that.

I would like to see something like this introduced in a later version of VB.NET
addhandler <object>.<event>, raiseevent <event>

And that should just be enough syntax for the compiler to automatically create the IL code to create a handler method that raises the event.
 
You just contradicted yourself. You say:
because as a parent class, I shouldn't have to know about all the events that a child class may handle and the types of objects that a child class has and all that.
and yet the example you show:
addhandler <object>.<event>, raiseevent <event>
requires you to know exactly that. I think the crux of the matter is what you said in your first post: you're lazy. What you suggest doesn't really make sense because there's be no way to create an EventArgs object. Passing the same EventArgs object isn't really best practice and, even if you did, there's no guarantee they'd be the same type for both events. If you want to write less code then you might like to look at creating your own code snippets.
 
I don't think I did - but i don't think i was very clear, so i'll try to clarify. My view is that a parent class should be responsible for catching the events FIRED by the calling class, but it shouldn't be responsible nor should it have any explicit knowledge about the events that are caught WITHIN the calling class.

What goes on within the calling class should be encapsulated within the calling class, and the only method of communication should be the public events made available.

And you're right, it is about laziness. Casading events up and down the stack seem to be a pretty common pattern so I don't see why they don't cater for it.

VB.NET:
addhandler <object>.<event>, raiseevent <event>
and
VB.NET:
AddHandler l2.l3.e3, AddressOf handler
would achieve the same thing, but the former would require one line of code as opposed to a line of code and a standard method.

And you could easily guarantee that the types of the events are the same, because if they changed the language, they would change the intellisense too and it would all be detected at design time.
 
I'm not sure I understand what you mean. If you have object A referenced inside object B referenced inside object C, and you want object C to handle an event of object A, how can object C see an event of object A if it can't see object A? If object B exposes object A publicly then then object C can handle an event of object A directly. If object A is private to object B then object C doesn't know object A exists, so there's no way it can handle one of its events.

If you think that that AddHandler/RaiseEvent line of yours would go in object B then object B has to know all about object A and its events, which you said earlier that you didn't think should have to be the case. That sounds like having cake and eating it to me.
 
This is what they've done in VB2008 for WPF projects with RoutedEvents. Winforms is like before, except you now are allowed Relaxed Delegates, ie you don't have to specify the parameters in handler signature if you don't need them.
 
Back
Top