Handling events in Visual Basic .NET can be confusing, especially for programmers moving up from VB 6 since there is a whole new dimension in event subroutines that was never there before. In VB 6, an event subroutine for a command button looks like this:
Private Sub Command1_Click()
' Your code goes here
End Sub
In VB.NET, it has morphed to this:
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
' Your code goes here
End Sub
I have to add line continuations when I write articles because all of the extra information just won't fit the article format here. What is all that extra information?
That's what this article is about.
As you can see, there are basically two new things added:
- The event subroutine arguments sender and e
- The Handles clause
The Handles clause allows the same subroutine to be used for all kinds of event calls. Suppose, for example, that you wanted a click in a Textbox and a Button to be processed by exactly the same code. No problem ...
Private Sub MyEventRoutine( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click, TextBox1.Click
MessageBox.Show( _
"Hey - I'm a Button AND a TextBox Handler!")
End Sub
Notice that the name of the subroutine (MyEventRoutine in this case) doesn't have to be the same as the event names in the Handles clause. A practical example of this technique was used in the article User Control Components in VB.NET.
The event handler arguments, sender and e, are the same for all event subroutines, in part, so you can code an event subroutine that handles different types of events like the example above.
If an event subroutine existed that had a different argument, it couldn't be handled by the same subroutine. But these arguments don't carry the same information all of the time, even though their names and types are the same. But there is a lot that is common.
The sender argument provides information about the event that was raised. There's a fairly small set of properties that sender provides directly. These properties carry just the basic information you need.
Equals
GetHashCode
GetType
ReferenceEquals
ToString
The sender arguement is often more useful if you instantiate an object using it. For example, if you are processing a Button control:
Dim myButton As Button = sender
If you are processing a PictureBox control:
Dim myPicBox As PictureBox = sender
Using these instances of controls, you can take advantage of the methods and properties of the control. For example, you can get the Name of a control:
Dim myButton As Button = sender
Debug.WriteLine(myButton.Name)
or
Dim myTextBox As TextBox = sender
Debug.WriteLine(myTextBox.Name)
What if you want to use the same subroutine, like the first code example, to report either the Name of the TextBox or the Button? You have two choices. Either code an If block to check which one was clicked or use the universal Object type (which is a lot slower). Here's some code that shows both choices in the same program:
Private Sub MyEventRoutine( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click, TextBox1.Click
If sender.GetType.ToString = "System.Windows.Forms.Button" Then
Dim myButton As Button = sender
Debug.WriteLine(myButton.Name)
ElseIf sender.GetType.ToString = "System.Windows.Forms.TextBox" Then
Dim myTextBox As TextBox = sender
Debug.WriteLine(myTextBox.Name)
End If
Dim myObject As Object = sender
Debug.WriteLine(myObject.Name)
End Sub
The first method is called "early binding" because Visual Basic already knows the type of the object when the code is compiled. The second method is called "late binding" because extra code has to be included in the compiled program that figures out how to retrieve the Name property once the actual Object type is determined.
SHARE