Thursday, March 12, 2020

The Vb.Net Sender and e Event Parameters

The Vb.Net Sender and e Event Parameters In VB6, an event subroutine, like Button1_Click, was much less complicated because the system called the subroutine strictly by name. If a Button1_Click event existed, the system called it. Its direct and straightforward. But in VB.NET, there are two major upgrades that make VB.NET SOOPercharged (thats 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. Use of Parameters Lets 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 hereEnd 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 IntegerShift As IntegerX As SingleY 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: LeftMiddleRightNoneXButton1XButton2 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 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 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. Protected Overrides Sub OnPaint( ByVal e As System.Windows.Forms.PaintEventArgs) Dim g As Graphics e.Graphics Other Examples 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 its 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, a programmer 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 One more example to nail down the point is a question that was sent in by Pierre in Belgium. Pierre was testing the equality of Button1 and sender using the Is operator for objects: If sender Is Button1 Then ... This is syntactically correct because sender and Button1 are both objects that can be referenced. And since sender really is identical with Button1, why doesnt it work? The answer depends on a keyword that is found a little earlier in the statement. First, lets check the Microsoft documentation for the Is operator. Visual Basic compares two object reference variables with the Is Operator. This operator determines if two reference variables refer to the same object instance. Notice that sender is passed ByVal. That means that a copy of Button1 is passed, not the actual object itself. So when Pierre tests to see if sender and Button1 are the same instance, the result is False. To test whether Button1 or Button2 has been clicked, you have to turn sender into an actual Button object and then test a property of that object. Text is usually used, but you could test a value in Tag or even the Location property. This code works: Dim myButton As ButtonmyButton senderIf myButton.Text Button1 Then