Author | Message | Time |
---|---|---|
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 |