Valhalla Legends Forums Archive | .NET Platform | [VB.NET] EventHandler, calling multiple

AuthorMessageTime
Grok
What are the restrictions on events?  In this sample, I am defining 3 events and calling them all one after another, but it seems only the first event fires each time.

Add Button1 and ListBox1 to a form.

[code]
Imports System
Imports System.Windows.Forms

Public Class Form1

    'class to carry the data for the raised event
    Public Class CustomEventArgs
        Inherits EventArgs
        Public id As Integer
        Public Sub New(ByVal id As Integer)
            Me.id = id
        End Sub
    End Class

    'delegate must be of the custom EventArgs class
    Public Delegate Sub CustomEventHandler(ByVal sender As Object, ByVal e As CustomEventArgs)

    'define some events
    Public Event Event1 As CustomEventHandler
    Public Event Event2 As CustomEventHandler
    Public Event Event3 As CustomEventHandler

    Public Sub ShowTheEventId(ByVal sender As Object, ByVal e As CustomEventArgs)
        ListBox1.Items.Add("event id = " + CStr(e.id))
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler Me.Event1, AddressOf Me.ShowTheEventId
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ea1 As CustomEventArgs = New CustomEventArgs(1)
        RaiseEvent Event1(Me, ea1)
        Dim ea2 As CustomEventArgs = New CustomEventArgs(2)
        RaiseEvent Event2(Me, ea2)
        Dim ea3 As CustomEventArgs = New CustomEventArgs(3)
        RaiseEvent Event3(Me, ea3)
    End Sub
End Class
[/code]
November 14, 2007, 1:55 PM
Grok
Oops, found the problem.  I had only added handler for Event1.

[code]    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler Me.Event1, AddressOf Me.ShowTheEventId
        AddHandler Me.Event2, AddressOf Me.ShowTheEventId
        AddHandler Me.Event3, AddressOf Me.ShowTheEventId
    End Sub[/code]

Works now.
November 14, 2007, 2:46 PM
Myndfyr
You should take a look into the defined pattern for raising events, what they use as "best practice."  I blogged about it - the blog is in C#, but it's essentially the same.  Part V in that blog talks about the pattern they suggest using.
November 14, 2007, 4:20 PM
Grok
I read your blog entry and the design pattern.  Seems to me my code is already correct.  What are you seeing?

Your part V sample wants to create a new Button class and override the predefined OnClick event.
My sample does not create any new derived class, and wants to define some new custom events to be called arbitrarily and carry a custom payload of data (id As Integer).
November 14, 2007, 4:57 PM
Myndfyr
You've got the delegate and event-args class right.  What they suggest is a protected virtual method:

[code]
Protected Overridable Sub OnEvent1(ByVal args As CustomEventArgs)
  If Not Event1 Is Nothing Then
    RaiseEvent Event1(Me, args)
  End If
End Sub
[/code]

Encapsulating the event call in the OnXxx method prevents you from generating an exception if there aren't any event handlers registered for the event and still provides a clean and easy way to invoke it without worry.
November 15, 2007, 4:53 AM
Grok
[quote author=MyndFyre[vL] link=topic=17171.msg174853#msg174853 date=1195102429]
You've got the delegate and event-args class right.  What they suggest is a protected virtual method:

[code]
Protected Overridable Sub OnEvent1(ByVal args As CustomEventArgs)
  If Not Event1 Is Nothing Then
    RaiseEvent Event1(Me, args)
  End If
End Sub
[/code]

Encapsulating the event call in the OnXxx method prevents you from generating an exception if there aren't any event handlers registered for the event and still provides a clean and easy way to invoke it without worry.
[/quote]

What is the scope of this encapsulated method?  Does it belong to the most specific class (Form) in which the events might be fired?
Also, the code as you have written it does not work in VB.NET 2005.  It is complaining that Event1 cannot be called directly(in the If conditional).

'Public Event Event1(sender As Object, e As CustomEventArgs)' is an event, and cannot be called directly. Use a 'RaiseEvent' statement to raise an event.

Complete code trying to implement your suggestion (contains errors):
[code]
Imports System
Imports System.Windows.Forms

Public Class Form1

    'class to carry the data for the raised event
    Public Class CustomEventArgs
        Inherits EventArgs
        Public id As Integer
        Public Sub New(ByVal id As Integer)
            Me.id = id
        End Sub
    End Class

    'delegate must be of the custom EventArgs class
    Public Delegate Sub CustomEventHandler(ByVal sender As Object, ByVal e As CustomEventArgs)

    'define some events
    Public Event Event1 As CustomEventHandler
    Public Event Event2 As CustomEventHandler
    Public Event Event3 As CustomEventHandler

    Protected Overridable Sub OnEvent1(ByVal args As CustomEventArgs)
        If Not Event1 Is Nothing Then
            RaiseEvent Event1(Me, args)
        End If
    End Sub

    Protected Overridable Sub OnEvent2(ByVal args As CustomEventArgs)
        If Not Event2 Is Nothing Then
            RaiseEvent Event2(Me, args)
        End If
    End Sub

    Protected Overridable Sub OnEvent3(ByVal args As CustomEventArgs)
        If Not Event3 Is Nothing Then
            RaiseEvent Event3(Me, args)
        End If
    End Sub

    Public Sub ShowTheEventId(ByVal sender As Object, ByVal e As CustomEventArgs)
        ListBox1.Items.Add("event id = " + CStr(e.id))
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler Me.Event1, AddressOf Me.ShowTheEventId
        AddHandler Me.Event2, AddressOf Me.ShowTheEventId
        AddHandler Me.Event3, AddressOf Me.ShowTheEventId
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.OnEvent1(New CustomEventArgs(11))
        Me.OnEvent2(New CustomEventArgs(12))
        Me.OnEvent3(New CustomEventArgs(13))
    End Sub

End Class
[/code]

Also, is the code in Button1_Click() the goal here?
November 16, 2007, 6:22 PM
Grok
Looks like I'll want to unregister each handler in some organized way, so I don't lose $2 million.
November 17, 2007, 1:42 PM

Search