Building Visual Basic .NET Windows Applications
This article is a sample chapter (Chapter 2) from VB .NET in 60 Minutes a Day, written by Bruce Barstow and Tony Martin, and published by Wiley.
Windows Application is really inappropriate as a project title, considering that it has the ability to be compiled to IL and ported to another operating system where it can be natively compiled. We'll use this term only because it's the name of the project type in .NET.
Working with .NET Forms and Controls
The basic unit of development in a .NET Windows application is (still) a form. Each form represents a single window in a running application. We add controls from the Toolbox to enhance a form's /*user interface.
The .NET version of a form has many new features. In .NET, all languages create a form based on the System.Windows.Forms.Form class in the common language runtime libraries. When I say "based on," I am actually referring to an OOP concept known as implementation inheritance, which allows one type to establish a relationship to another type for the purpose of inheriting functionality. Look at it this way: Visual Basic has always had forms, but we have never had to design into them the ability to be resized or minimized or to display a blue title bar, and so on. All that functionality was inherited from a generic Form object when we added the form to our project. Even in Visual Basic 6 we could declare a variable of type Form, and a new object would be created in memory that had its own Name, hwnd, caption, and so on. Even the first piece of code you see in Visual Basic .NET requires that you have some understanding of Inheritance, as you can see in the Visual Basic .NET code that follows. This code shows the relationship between a form and its immediate base class:
Public Class Form1 Inherits System.Windows.Forms.Form End Class
Forms Are Objects
Visual Basic has always created forms as objects, but until Visual Basic .NET we had not seen any underlying code to prove that. Quite possibly the biggest change in Visual Basic .NET is that all the underlying details of how things are done are no longer abstracted away from us. Although classes are formally discussed in Chapter 6, "Building Class Libraries in .NET," for now you need to understand two basic points. The first point is that all things in .NET are objects. The second point is that all objects are based on a template that a programmer built using code. The most common template for an object is called a class. The description for an object in this chapter will be limited to a self-contained entity that has properties to describe it, methods that provide behaviors, and events that allow it to respond to messages.
Form1 is actually a class called Form1 and at runtime, any number of actual Form1 objects can be created based on that class. This chapter focuses on many aspects of designing Windows applications, but as we're using different forms, controls, and other objects, I need you to remember that all these things are built using these object templates.
A Change of Events
Events in Visual Basic .NET are very different from what they were in Visual Basic 6. Event names, the way they are used, and their sheer number have understandably changed in .NET because all controls in .NET were built from the ground up.
For example, the event for a Visual Basic 6 text box that occurred as the user typed into that text box is called the Change event. In .NET, that event is now implemented as the TextChanged event. Besides the name change, the next major difference is that this event now takes sender and e arguments. In Visual Basic we used control arrays when multiple controls needed to share code. In Visual Basic .NET we map two events to the same event handler. Finally, the keyword Handles is used to indicate that a subroutine is to handle the TextChanged event for the text box txtFirstName. Although we might think from our prior experience with Visual Basic that this isn't necessary, keep in mind that the things we're using to build our applications in .NET are based on the CLS and a solid object-oriented foundation. The more you learn about the underlying foundation of .NET, the easier it will be to understand why some things are so different from Visual Basic 6. The following examples contrast the difference between the Change and TextChanged events.
Here is an example in Visual Basic 6:
Private Sub Text1_Change() End Sub
Here is an example in Visual Basic .NET:
Private Sub txtFirstName_TextChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles txtFirstName.TextChanged End Sub
Classroom Q & A
Q: If the .NET version of this code says that it handles the TextChanged event for txtFirstName, could I name this subroutine anything I want?
A: In Visual Basic we just write the code in the event and don't differentiate between the event and event handler. Here, we have a predefined set of events that can be raised in an object and we need to write custom handlers to handle those events. We can name it whatever we want.
Q: So, I take it that sender is kind of like the index parameter from Visual Basic?
A: Well, in a way. It is used to identify which object received the event that caused the event handler to execute. By accessing properties of the sender object, we can find out exactly which control received the event.
Q: How do we make it so that more than one control can use the same event handler?
A: You just append more information to the Handles part of the event handler declaration. Lab 2.1 demonstrates that process.
Lab 2.1: Working with Event Handlers
This lab demonstrates the association between events and event handlers. We will create three text boxes. The first two contain the first and last names of an individual. As either the first or last name is changed, the third text box will dynamically display the resulting email address. To start, we will use separate TextChanged events for capturing changes to the first and last names but will quickly change our implementation to a more efficient event handler.
Perform the following steps:
- Start a new Visual Basic Windows application.
- Drag three TextBox controls and three Labels to the form.
- Change properties for controls by selecting them at design time and entering a new value for the desired property in the Properties window. Change the following properties for the six controls you just added to Form1.P: txtFirstName_TextChanged to txtLastName_ TextChanged and test the application again. This time the results were correct, but the method we used to obtain those results used redundant code.
- Remove the entire txtLastName_TextChanged event handler.
- Change the name of the txtFirstName_TextChanged event handler to Names_TextChanged.
- Add the following code to the end of the declaration for Names_TextChanged so that the same event handler handles the TextChanged events for both text boxes.
What you should see is:
Private Sub Names_TextChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles txtFirstName.TextChanged, _ txtLastName.TextChanged txtEmail.Text = txtFirstName.Text & "." & txtLastName.Text & _ "@somecompany.com" End Sub
- 7. Run the application again. Functionally, it still works the same but with half the code. This event-handling process uses a concept known as delegation, discussed in Chapter 7, "Extending Visual Basic .NET Classes."
For now, let's just view our Names_TextChanged event handler as a method of the Form1 class that handles the TextChanged event for two text boxes. The next step will be to get used to the different controls and events used in building Windows forms.
The Controls Collection
Each form has a collection called Controls, which contains all the controls on that form. The Contains method (not specific to a form) returns a boolean value that indicates whether one control is contained in another.
Dim i As Integer For i = 0 To Me.Controls.Count - 1 If Me.Controls(i).Contains(mycontrol) Then MessageBox.Show(Me.Controls(i).Name) End If Next I
Most of the standard controls used on Windows forms are part of the System.Windows.Forms assembly in System.Windows.Forms.dll.
Familiar Controls or Just Familiar Looking?Many controls that look identical to their predecessors act quite differently in .NET. Let's take the scrollbar controls as an example. The first thing you'll see regarding scrollbars in .NET is that instead of having a single control with an orientation property, the .NET Toolbar has separate vertical (VScrollBar) and horizontal scrollbar (HScrollBar) controls. The scrollbars have Minimum and Maximum properties that are typically mapped to the target range they are used to scroll through. These properties used to be Min and Max in Visual Studio 6. The following exercise demonstrates much more than scrollbars. In Lab 2.2 you're going to use HScrollBar controls to see how even the simplest of tasks have changed for Visual Basic programmers.
Lab 2.2: Controls in .NET
.NET controls are smarter than their predecessors. They can adapt to their surroundings. We'll be using three HScrollBar controls to control the background color of the current form by individually setting the red, green, and blue values (RGB) of a Color object.
Perform the following steps:
- Start a new Visual Basic Windows application.
- Drag a GroupBox (used to be called a Frame control) to Form1.
- Drag three HScrollBar controls inside the GroupBox.
- Because each of these HScrollBar controls will be setting the RGB values, we need to set their Minimum and Maximum values to match the possible values for RGB. For each control, set the Maximum property value to 255 and leave the Minimum property value at 0. The HScrollBar1 control will change the red, HScrollBar2 will change the green, and HScrollBar3 will change the blue value of a Color object. Because RGB values are always in red, green, blue order and have values ranging from 0 to 255, a value of 0,0,255 indicates pure blue.
- Add the following event handler to handle the Scroll event for all three HScrollBar controls:
Private Sub ScrollAll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles HScrollBar1.Scroll, HScrollBar2.Scroll, HScrollBar3.Scroll Me.BackColor = Color.FromArgb(HScrollBar1.Value, HScrollBar2.Value, HScrollBar3.Value) End Sub
- Run the application. Use the scrollbars to change the BackColor of Form1, but watch the GroupBox controls color! The GroupBox has the inherent ability to change the color of its border in relation to its immediate container, as shown in Figure 2.1. We deduce from this that there is an event that notifies the GroupBox that such a change was made. The System.Windows.Forms.Form and System.Windows.Forms.Control classes have many events we're not used to seeing yet, such as ForeColorChanged and BackColorChanged that make features like this possible. All of our controls and forms are based on (inherited from) these two classes.
Color is a class defined in System.Drawing. If you look at the References section in the Solution Explorer, you will see that our application has a reference to the System.Drawing assembly. That is why we can use the Color class.
If you're starting to believe that I'm trying to get you used to the object-oriented nature of .NET, you're right! If the objects, classes, and inheritance are all still confusing, don't be discouraged. We haven't even formally explored those concepts yet. By the time we get to a discussion on classes and objects, you will have quite a few examples to fall back on. For now, understand that we are in a pure object-oriented environment and nothing is abstracted away from us as it was in Visual Basic 6. These two truths will drive your application development in .NET more than you may realize at this point, but be excited; with this environment comes a developmental power and elegance previously lacking in Visual Basic.
Figure 2.1 The GroupBox control dynamically adjusts to its parent's BackColor property by changing the color of its own border.