The Form object triggers several events. The most important are Activated, Deactivate, Form-Closing, Resize, and Paint.
The Activated and Deactivate Events
When more than one form is displayed, the user can switch from one to the other by using the mouse or by pressing Alt+Tab. Each time a form is activated, the Activated event takes place. Likewise, when a form is activated, the previously active form receives the Deactivate event. Insert in these two event handlers the code you want to execute when a form is activated (set certain control properties, for example) and when a form loses the focus or is deactivated. These two events are the form’s equivalents of the Enter and Leave events of the various controls. Notice an inconsistency in the names of the two events: the Activated event takes place after the form has been activated, whereas the Deactivate event takes place right before the form is deactivated.
The FormClosing and FormClosed Events
The FormClosing event is fired when the user closes the form by clicking its Close button. If the application must terminate because Windows is shutting down, the same event will be fired as well. Users don’t always quit applications in an orderly manner, and a professional application should behave gracefully under all circumstances. The same code you execute in the application’s Exit command must also be executed from within the closing event. For example, you might display a warning if the user has unsaved data, you might have to update a database, and so on. Place the code that performs these tasks in a subroutine and call it from within your menu’s Exit command, as well as from within the FormClosing event’s handler.
You can cancel the closing of a form by setting the e.Cancel property to True. The event handler in Listing 5.2 displays a message box informing the user that the data hasn’t been saved and gives him a chance to cancel the action and return to the application.
Listing 5.2: Cancelling the Closing of a Form
Public Sub Form1_FormClosing(...) Handles Me.FormClosing
Dim reply As MsgBoxResult
reply = MsgBox("Document has been edited. " & _
"OK to terminate application, Cancel to " & _
"return to your document.", MsgBoxStyle.OKCancel)
If reply = MsgBoxResult.Cancel Then
e.Cancel = True
The e argument of the FormClosing event provides the CloseReason property, which reports how the form is closing. Its value is one of the following members of the CloseReason enumeration: FormOwnerClosing, MdiFormClosing, None, TaskManagerClosing, WindowsShutDown. The names of the members are self-descriptive, and you can query the CloseReason property to determine how the window is closing.
The FormClosed event fires after the form has been closed. You can find out the action that caused the form to be closed through the e.CloseReason property, but it’s too late to cancel the closing of the form.
The Resize, ResizeBegin, and ResizeEnd Events
The Resize event is fired every time the user resizes the form by using the mouse. With previous versions of VB, programmers had to insert quite a bit of code in the Resize event’s handler to resize the controls and possibly rearrange them on the form.With the Anchor and Dock properties, much of this overhead can be passed to the form itself. If you want the two sides of the form to maintain a fixed ratio, however, you have to resize one of the dimensions from within the Resize event handler. Let’s say the form’s width-to-height ratio must be 3:4. Assuming that you’re using the form’s height as a guide, insert the following statement in the Resize event handler to make the width equal to three-fourths of the height:
Private Form1_Resize(...) Handles Me.Resize
Me.Width = (0.75 * Me.Height)
The Resize event is fired continuously while the form is being resized. If you want to keep track of the initial form’s size and perform all the calculations after the user has finished resizing the form, you can use the ResizeBegin and ResizeEnd events, which are fired at the beginning and after the end of a resize operation, respectively. Store the form’s width and height to two global variables in the ResizeBegin event and use these two variables in the ResizeEnd event handler.
The Scroll Event
The Scroll event is fired by forms that have their AutoScroll property set to True when the user scrolls the form. The second argument of the Scroll event handler exposes the OldValue and NewValue properties, which are the displacements of the form before and after the scroll operation. This event can be used to keep a specific control in view when the form’s contents are scrolled.
The AutoScroll property is handy for large forms, but it has a serious drawback: It scrolls the entire form. In most cases, we want to keep certain controls in view at all times. Instead of a scrollable form, you can create forms with scrollable sections by exploiting the AutoScroll properties of the Panel and/or the SplitContainer controls. You can also reposition certain controls from within the form’s Scroll event handler. Let’s say you have placed a few controls on a Panel container and you want to keep this Panel at the top of a scrolling form. The following statements in the form’s Scroll event handler reposition the Panel at the top of the form every time the user scrolls the form:
Private Sub Form1_Scroll(...) Handles Me.Scroll
Panel1.Top = Panel1.Top + (e.NewValue - e.OldValue)
The Paint Event
This event takes place every time the form must be refreshed, and we use its handler to execute code for any custom drawing on the form. When you switch to another form that partially or totally overlaps the current one and then switch back to the first form, the Paint event will be fired to notify your application that it must redraw the form. The form will refresh its controls automatically, but any custom drawing on the form won’t be refreshed automatically. We’ll discuss this event in more detail in Chapter, “Drawing and Painting with Visual Basic.NET 2008,” in the presentation of the Framework’s drawing methods.