Beginning Visual Basic 2005 Express Edition - From Novice To Professional (2006)
.pdf230 C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S
Try It Out: Opening and Closing Windows
Start up a new WinForms project and drop two buttons onto the form that appears, as in Figure 9-2.
Figure 9-2. Drop two buttons onto the form. These will be used to control opening and closing windows.
Set the Text properties of the buttons as in the screen shot. Set the Name properties of the controls to openButton and closeButton.
Now you can add a second form to the program. Right-click on the name of the project in the Solution Explorer, and choose Add Windows Form from the submenu that appears.
The Add New Item dialog in Figure 9-3 appears.
As you can see, there are plenty of different types of forms you can add. In fact these are really all standard forms, but they have had some code and design work done on them to make your life easier. You can also specify the name of the form here. Notice at the bottom of the dialog there is a text box labeled Name. Type SecondWindow.vb into the text box, select the plain old empty Windows form from the dialog, and click the Add button.
After a short delay, the Solution Explorer will update to show the new form in the project, and the new blank form will also appear in the form editor. Let’s go ahead and add a label to this form so that it stands out as your new window. Drop a Label control onto the form as in Figure 9-4.
C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S |
231 |
Figure 9-3. When you choose to add a new item to the project, Visual Basic 2005 Express displays the Add New Item dialog.
Figure 9-4. Drop a Label control on the form, and use its Text and Font properties to make it look like this.
232 C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S
Okay, so now you have two forms in your application, you need to get some code added to those buttons on the first form to work with the second. Use the tabs at the top of the form editor to return to Form1’s design mode (see Figure 9-5).
Figure 9-5. As you add new files to the project, you can move between them by using both the Solution Explorer and the tabs at the top of the designer.
Double-click the Open Window button to drop into its Click event, and you’ll add code to open up your new window.
Because a form is a class, all you need to do is instantiate an object from it. Now you know why we spent so long looking at how to do this earlier in the book.
Private Sub openButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles openButton.Click
Dim newWindow As New SecondWindow()
End Sub
Notice that the second form’s class name is SecondWindow, and the filename in the Solution Explorer is also SecondWindow.vb. When you add a new form to a project and set its name, VB Express is smart enough to set the Name property of the new form to be the same as the filename, which saves you the hassle of setting it yourself.
Instantiating the second form just creates a new window in memory; it doesn’t actually show it on-screen. To display it, you need to call a method on your newWindow object:
Private Sub openButton_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles openButton.Click
Dim newWindow As New SecondWindow() newWindow.Show()
End Sub
Run the program now. When the window comes into view, click the Open Window button to display the second window. There’s a bit of a problem with the program currently, though. Click the Open Window button a few times—you may need to rearrange the windows on-screen in order to find it (see Figure 9-6). Each time the Open Window button is clicked, it creates a brand new instance of the second window and displays it. This may be fine for some applications, but it’s not at all what we were aiming for.
C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S |
233 |
Figure 9-6. Clicking the OpenWindow button multiple times creates multiple instances of the second window and shows them all.
What we’d really like to happen is for the Open Window button to create just one instance of the second window. You can do that by making the local newWindow variable in the button’s click handler a member of the class, instead of local to the subroutine. Stop the program that is running by closing down all the windows, or clicking the Stop button on the VB Express toolbar, and change the code for the click handler, like this:
Public Class Form1
Dim newWindow As SecondWindow = Nothing
Private Sub openButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles openButton.Click
If newWindow Is Nothing Then newWindow = New SecondWindow()
End If
newWindow.Show() End Sub
End Class
234 C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S
By moving the newWindow variable out of the event handler, it becomes a member variable accessible to all code in your first form. Initially, you set the value of the variable to Nothing, effectively meaning that it’s empty and doesn’t actually reference a live object. The code in the click handler then just has to check whether the newWindow variable is still Nothing, meaning the second window is not shown yet. If that’s the case, a new window is created and shown.
In fact, moving the newWindow variable into the class makes it relatively easy for you to add code now to the Close Window button. Go back to the designer view for Form1 and double-click the Close Window button to open up the code editor for its click handler. Add some code to work with the newWindow variable, like this:
Private Sub closeButton_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles closeButton.Click
If Not newWindow Is Nothing Then newWindow.Close()
newWindow = Nothing End If
End Sub
If you run the program now, you’ll find that clicking the Open Window button produces only one second window. You can also now click the Close Window button to shut the second window.
There’s still a problem, though. If you open a second window and then close the window down by hand, by clicking its Close icon at the top right of the window, you can’t go ahead and click the Open Window button again; as far as it’s concerned, the window is still open.
There are a number of ways around this. You could get the second window to call a method on the first when it closes down, but that’s a little complex right now. You could change the window style to prevent the second window from showing a Close Window button at all, but that’s a little forceful from a user experience perspective.
A much better solution exists using the Application class. As the name suggests, Application has a bunch of methods and properties that you can use to find out the state of the current application. It has an array property called OpenForms that you can use to get at each and every form the application has opened. You can also just look at its Count property to see how many forms are open. (An alternate way to see which windows are open, for example, is to use a For Each loop over the OpenForms collection.) Go back to the code for the Open Window and Close Window button Click events and change them, like this:
Public Class Form1
Dim newWindow As SecondWindow = Nothing
Private Sub openButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles openButton.Click
C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S |
235 |
If Application.OpenForms.Count = 1 Then
newWindow = New SecondWindow()
End If
newWindow.Show()
End Sub
Private Sub closeButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles closeButton.Click
If Application.OpenForms.Count = 2 Then newWindow.Close()
End If
newWindow = Nothing
End Sub End Class
After this change, the Open Window button will work only if there is only one form (the first form) open. Similarly, the Close Window button will work only if there are two windows open (the first and the second). Try the app now, and it works perfectly. You can open a window by using the Open Window button, and close it by either using the Close Window button or by manually closing the window by clicking on its own Close icon. Either way, the Open Window button will still work perfectly (see Figure 9-7).
Figure 9-7. By checking the Application.OpenForms.Count property, you can ensure that only one second window is ever displayed.
Of course, the OpenForms array provides a lot more information than just a Count property. You could iterate through it with a For Each command and actually grab each and every form that’s opened and interrogate their properties.
236 C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S
Styles
I mentioned in the previous section that you can change the style of a form to remove the standard Close icon on the window. In fact, you can do much more than that. You can remove each of the Close, Maximize, and Minimize icons individually, as well as change the actual border style and title bar style of the window. By doing this, you can also prevent the window from resizing at all. There are even properties to control the maximum and minimum sizes that a user can make a window. If you want to go really nuts, you can even make the window transparent. The properties to do all this are shown in Table 9-1.
Table 9-1. Properties That Control How the Window Looks at Runtime
Property |
Description |
ControlBox |
Set to False to remove the Close, Maximize, and Minimize icons from the |
|
form. |
MaximizeBox |
Set to False to disable the Maximize icon from the window. |
MinimizeBox |
Set to False to disable the Minimize icon from the window. |
Opacity |
Set to a value between 0 and 100 to control transparency of the window. For |
|
example, set the property to 0 and it becomes completely transparent. |
MaximumSize |
Set MaximumSize.Width and MaximumSize.Height to limit the maximum size a |
|
user can resize a window to. |
MinimumSize |
Set MinimumSize.Width and MinimumSize.Height to limit the smallest size a |
|
user can resize a window to. |
FormBorderStyle |
Select a style from the drop-down list in the Properties window to govern |
|
how the border and title bar look. Possible values are None, FixedSingle, |
|
Fixed3D, FixedDialog, Sizable, FixedToolWindow, and SizableToolWindow. |
|
|
The great thing about writing Windows applications with VB Express is that it’s such a visual development environment. All of those properties (with the exception of the Opacity property) can be changed at design time and will instantly update the form in the designer. Go ahead and play with them to see what they all do.
C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S |
237 |
For the Opacity property, just start up a new WinForms project, set the Opacity property of the main form in the project to 25, and run the project to see what happens (see Figure 9-8).
Figure 9-8. The Opacity property can be used to make forms transparent. This is good for informational dialogs, which I’ll cover later in this chapter.
The Life and Times of a Form
Forms also support a lot of events that you can code up to respond to changes in the form’s state. In fact, forms have so many events that it can be hard at times to know just which one you should add code to.
238 C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S
When a form loads up at runtime, the following events fire, in the order shown in Table 9-2.
Table 9-2. Events That Fire on a Form When It Is First Shown
Event |
Description |
Move |
This event fires when a form is moved. At start-up, the location of |
|
the form is set before anything else happens; hence the event fires. |
LocationChanged |
As soon as a move is complete and the form has determined where |
|
on the screen it lives, the LocationChanged event fires. |
StyleChanged |
Whenever a form’s FormBorderStyle changes, or its control box or |
|
Maximize or Minimize icons are enabled or disabled, this event |
|
fires. |
BindingContextChanged |
This is used for data binding, something I cover much later in the |
|
book. The event fires whenever the data sources (database tables |
|
and so on) that it is supposed to display change. |
Load |
This used to be the first event to fire on a form in classic Visual Basic. |
|
In .NET, though, this event fires directly before a form is displayed. |
Layout |
After the form is displayed, it may need to reposition any controls it |
|
contains (if they are anchored in position, or docked). This event |
|
fires before that repositioning happens. |
VisibleChanged |
This event fires whenever a form’s Visible property changes from |
|
True to False, or vice versa. |
Activated |
After the form has been positioned and displayed and has |
|
rearranged itself, this event fires to let you know that it is now the |
|
current active form. |
Shown |
This event fires after everything else to let you know that the form is |
|
now visible and ready for use. |
Paint |
This event fires whenever the form, or a control, needs to redraw |
|
itself. You would typically put code here to do any custom drawing |
|
you need, something I cover later in the book. |
|
|
When the form closes down, the events in Table 9-3 fire.
Table 9-3. Events That Fire on a Form When It Closes Down
Event |
Description |
MouseCaptureChanged |
This means the form is no longer responding to mouse events, and is |
|
the first event to fire when it closes. It stops the user from queuing up |
|
lots of events to a form that is about to go away. |
FormClosing |
This event fires just before the form closes down. It can be cancelled, |
|
to stop the form closing, by setting e.Cancel to True (e is the name of |
|
the second parameter to the event handler). |
FormClosed |
This event fires after the form successfully closes down. |
Deactivate |
When the form no longer has focus (the user clicks on a different |
|
form, switches application, or closes the form down), this event fires. |
|
|
C H A P T E R 9 ■ W I N D O W S A N D D I A L O G S |
239 |
That’s a lot of events for something so simple as opening and closing a window, I think you’ll agree. Incidentally, this sequence isn’t documented in the online help and so to confirm it I simply started a new WinForms project and coded up every single event handler. Feel free to do the same if you want to explore the events in more detail; it’s a great way to become familiar with all the events that a form offers. Also bear in mind that there are still a great many events not included here that fire on a form, just as they would on a normal control, such as Click and DoubleClick.
The most commonly used of all these events are probably the Load, Paint, FormClosing, and FormClosed events. I’ll cover Paint later in the book when we look at drawing and graphics in .NET.
The Load event is used a lot to set up any data that might be needed by the form. In fact, if you eventually decide to move into the world of ASP.NET web development, you’ll find that WebForms also have a Load event that gets used for the same thing. A typical example might be loading up data from a database and storing it into member variables in the form class that the controls on the form use, or running some code to do something special with the form’s controls that perhaps .NET doesn’t support out of the box.
FormClosing and FormClosed, on the other hand, are used to control shutting down of a form. You get a FormClosing event when the user, or program code, tries to shut down a form. This event gives you the opportunity to cancel the form closing, typically by displaying a message box that asks the user whether he is really sure he wants to close the form down, perhaps because there’s data on the form that still needs to be saved.
The FormClosed event, on the other hand, is the point of no return for a form. If that event fires, you know for certain that the form is about to shut down. Therefore, most people use that event to contain code that must be run as the last thing the form does before it goes away completely.
Try It Out: Stopping a Form from Closing
Start up a new WinForms project and drop a CheckBox control on the form. Set the Text property of the control as shown in Figure 9-9.
Figure 9-9. Drop a CheckBox control onto your form and set its Text property as shown.