Question Events and binding their EventHandlers

sebastian.

Member
Joined
Sep 20, 2009
Messages
17
Programming Experience
1-3
Hi everybody!

I have a problem with binding my EventHandlers at the right time.
Here's a pseudo code of my 1. version:

VB.NET:
Public Class MainClass

Public Sub Main()
Dim myUserControl as UserControlClass = new UserControlClass()
AddHandler myUserControl.myUserControlEvent, myUserControlEventHandler
End Sub

Private Sub myUserControlEventHandler()
...
End Sub
End Class

The event is raised during the initialization of my
VB.NET:
myUserControl
Object, but it isn't captured by its EventHandler in the
VB.NET:
MainClass
...that's obvious, because the Handler is added to late.

But I have the same problem when I modify my code like this:

VB.NET:
Public Class MainClass

Public Sub Main()
Dim WithEvents myUserControl as UserControlClass = new UserControlClass()
End Sub

Private Sub myUserControlEventHandler() Handles myUserControl.myUserControlEvent
...
End Sub
End Class

I thought this 2. version would use "static binding" of the events during compile time. But it seems, that they are also bound to late, namely after the initialization of my UserControl has finished and so they aren't captured again.

So is there a possibility to bind the events "at the beginning" so that my events, which are raised during the init of my UserControlClass are handled in my MainClass?

Thanks in advance!

Greetings, Sebastian
 
RaiseEvent help says this:
Non-shared events should not be raised within the constructor of the class in which they are declared. Although such events do not cause run-time errors, they may fail to be caught by associated event handlers. Use the Shared modifier to create a shared event if you need to raise an event from a constructor.
 
Hi John,

unfortunatelly changing the event declaration in the "UserControlClass" to this:

VB.NET:
Public Shared myUserControlEvent(...)

and binding it to the EventHandler in the "MainClass" like this:

VB.NET:
Private Sub myUserControlEventHandler() Handles myUserControl.myUserControlEvent
...
End Sub

doesn't work either. But I think that's what they/you meant with "using the shared modifier".

What am I doing wrong?

Sebastian
 
You can't use a Handles clause to handle Shared events. A Handles clause requires a field declared WithEvents. Local variable cannot be declared WithEvents. Besides that, Shared events are members of the class, not any specific instance of the class. If you have code like this:
VB.NET:
Public Class EventRaisingClas

    Public Shared Event SomeEvent As EventHandler

    '...

End Class
then you need to have code like this:
VB.NET:
Public Class EventHandlingClass

    Public Sub New
        AddHandler EventRaisingClass.SomeEvent, AddressOf HandleSomeEvent
    End Sub

    Private Sub HandleSomeEvent(ByVal sender As Object, ByVal e As EventArgs)
        '...
    End Sub

    '...

End Class
Notice that you're adding a handler to the event of the class, not of an instance of the class.
 
I'm sorry, but I don't get it working during initialization (see my first post).

Let's say I have the following two Windows Forms:

VB.NET:
Public Class frmEventHandlingClass

    Private Sub btnShowSecondForm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowSecondForm.Click

        frmEventRaisingClass.Show()

        AddHandler frmEventRaisingClass.SomeEvent, AddressOf EventHandlerSomeEvent

    End Sub

    Private Sub EventHandlerSomeEvent()
        MsgBox("event raised")
    End Sub

End Class

VB.NET:
Public Class frmEventRaisingClass

    Public Shared Event SomeEvent()

    Public Sub New()

        InitializeComponent()

        RaiseEvent SomeEvent()

    End Sub

End Class

Now I want to raise the event during initialization of the EventRaisingClass -> in the constructor.

And that doesn't work...so what exactly could be wrong in my code above? :confused:

Thanks for trying to help me :)!

Greetings, Sebastian
 
You're add the handler after you've shown the form. If the event is being raised in the constructor then handling it after the form has been shown is a bit late isn't it? If the event is raised in the constructor then you need to add the handler before the constructor is executed.
 
Exactly.

And that's why I thought, I'd need to use static binding of the event handlers (-> see my first post):

VB.NET:
Private Sub EventHandlerSomeEvent() Handles frmEventRaisingClass.SomeEvent

But it seems, this is also bound to late...and I thought it's bound during compile time.

Than I tried this thing with
VB.NET:
Public Shared Event SomeEvent()
but that didn't work neither (-> neither with the AddHandler Code nor with the Handles Code in my EventHandlingClass).

So how can I "catch" such an event???

Sebastian
 
Everything you need has already been provided. As I have already said, you can NOT use a Handles clause with a Shared event. You MUST use AddHandler and, if you want to handle an event that's raised in the constructor, you MUST add the handler BEFORE the constructor is invoked. I just did the following, which is exactly what we've already explained, and it worked as expected:
VB.NET:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, _
                           ByVal e As EventArgs) Handles MyBase.Load
        AddHandler Form2.SayHello, AddressOf Form2_SayHello
    End Sub

    Private Sub Button1_Click(ByVal sender As Object, _
                              ByVal e As EventArgs) Handles Button1.Click
        Form2.Show()
    End Sub

    Private Sub Form2_SayHello(ByVal sender As Object, _
                               ByVal e As EventArgs)
        MessageBox.Show("Hello")
    End Sub

End Class
VB.NET:
Public Class Form2

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        RaiseEvent SayHello(Me, EventArgs.Empty)
    End Sub

    Public Shared Event SayHello As EventHandler

End Class
 
Hi!

I tried the same (adding the handler before the eventraising object is created) in my "big" application, which is an addon for AutoCAD and it crashed with some AutoCAD error.
So I thought, I can't put it before my eventraising object is created.

But your version works perfectly.

So my mistake was, I wrote:

VB.NET:
AddHandler myOBJECT.myEvent, AddressOf myEventHandler

instead of

VB.NET:
AddHandler myCLASS.myEvent, AddressOf myEventHandler

And that, of course, couldn't work! Now everythings fine...

So thanks again for all your explanations!

Sebastian
 
Back
Top