In older versions of Visual Basic, event subroutines, such as the "Button1_Click" subroutine, are much less complicated because the system calls the subroutine strictly by name. If a Button1_Click event exists, the system calls it. It's direct and straightforward. But in VB.NET, there are two major upgrades that make VB.NET SOOPercharged. (That's "OOP" for Object Oriented Programming.)
- The "Handles" clause controls whether the system calls the subroutine, not the name.
- The sender and e parameters are passed to the subroutine.
Let's look at a simple example to see the difference that parameters make in VB.NET.
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
' Your code goes here
End Sub
Event subroutines always receive a "sender" object and a system EventArgs parameter "e". Because the EventArgs parameter is an object, it supports whatever properties and methods are necessary. For example, the old VB6 MouseMove event subroutine used to receive four parameters:
- Button As Integer
- Shift As Integer
- X As Single
- Y As Single
When more advanced mice came out with more buttons, VB6 had a real problem supporting them. VB.NET only passes one MouseEventArgs parameter but it supports a lot more properties and methods. And each of them are objects that support even more. For example, the e.Button property contains all these properties:
- Left
- Middle
- Right
- None
- XButton1
- XButton2
... and a whole list of methods. If someone invents a "trancendental" mouse with a "virtual" button, VB.NET will only have to update the .NET Framework to support it and no previous code will never break as a result.
There are a number of .NET technologies that absolutely depend on these parameters. For example, since your PC usually only has a single screen to display graphics, your code has to merge the graphics it creates into the same image used by Windows. For that reason, a single "graphics" object has to be shared. The GDI+ (Windows graphics) tutorial, explains that the major way that your code is able to use that "graphics" object is to use the e parameter that is passed to the OnPaint event with the PaintEventArgs object. Here's an example:
Protected Overrides Sub OnPaint( _
ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
What else can you do with these parameters? To illustrate, suppose you want to find whether a string, perhaps something you entered into a Textbox, exists in any one of a collection of other Textboxes when you click on one. You could code a few dozen virtually identical subroutines for each Textbox:
If TextBox42.Text.IndexOf( _
SearchString.Text) = -1 _
Then NotFound.Text = _
"Not Found"
But it's a lot easier to code just one and let it handle all of them. The sender parameter will reveal which Textbox was clicked.
Private Sub FindIt _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles TextBox1.Enter, _
TextBox2.Enter, _
. . . and on and on ...
TextBox42.Enter
Dim myTextbox As TextBox
myTextbox = sender
Dim IndexChar As Integer = _
myTextbox.Text.IndexOf( _
SearchString.Text)
If IndexChar = -1 Then _
NotFound.Text = "Not Found" _
Else _
NotFound.Text = "Found It!"
End Sub
Recently, an About Visual Basic reader asked me for a better way to "delete the line that was clicked in any of six specified lists." He had it working in a couple of dozen lines of code that simply confused me. But using sender, it was really quite simple:
Private Sub ListBox_Click( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles ListBox1.Click, ListBox2.Click
Dim myListBox As New ListBox
myListBox = sender
myListBox.Items.RemoveAt(myListBox.SelectedIndex)
End Sub


