204
5.2 Control Events
Controls on a form are represented in code as fields—one field for each control. For example, when the Visual Studio .NET Windows Forms Designer is used to add a text box to a form, the following
declaration is added to the form class:
Private WithEvents TextBox1 As System.Windows.Forms.TextBox This declaration doesnt instantiate the control; it only defines a field that can hold a reference to a
control of type TextBox. The control is instantiated in the InitializeComponent subroutine, which is called in the Form classs constructor. The code that instantiates the control looks like this:
Me.TextBox1 = New System.Windows.Forms.TextBox As discussed in
Chapt er 2 , when a field declaration includes the
WithEvents keyword, the parent
class can handle events that the referenced object raises. To do so, the parent class must define a handler method having the appropriate signature, and the definition of the method must include a
Handles clause to link the method to the appropriate event on the appropriate object. For example,
here is the definition of a handler method for the Click event of TextBox1: Private Sub TextBox1_Click _
ByVal sender As Object, _ ByVal e As System.EventArgs _
Handles TextBox1.Click ...
End Sub
The event-handler method can be given any name, but it is a common convention to use a name of the form
FieldName_EventName . The event-handler methods signature must correspond to the
signature of the event being handled. By convention, event signatures have two parameters: sender
and e
. The sender
parameter is always of type Object and holds a reference to the object that raised the event. The
e parameter is of type EventArgs—or of a type that inherits from EventArgs—and holds
a reference to an object that provides any extra information needed for the event. Events that pass a generic EventArgs argument have no event information to pass. Events that pass an argument of an
EventArgs-derived type pass additional information within the fields of the passed object.
The correct signature for handling a specific event can be determined either by referring to the controls documentation or by using Visual Studio .NETs built-in object browser. In addition, the Visual
Studio .NET Windows Forms Designer can automatically generate a handler-method declaration for any event exposed by any control on a given form.
5.3 Form and Control Layout
Windows Forms allows developers to lay out sophisticated user interfaces that are capable of intelligently resizing without writing a line of code. Previously, developers writing desktop applications
for Windows typically spent a good deal of time writing resizing code to handle the placement of controls on the form when the user resized the form. The .NET platform, however, allows you to define
a controls layout and size by setting a few properties.
5.3.1 The Anchor Property
The Anchor property lets a control anchor to any or all sides of its container. Each anchored side of the control is kept within a constant distance from the corresponding side of its container. When the
container is resized, its anchored controls are repositioned and resized as necessary to enforce this rule. The Anchor property is defined by the Control class in the System.Windows.Forms namespace
and so is inherited by all controls and forms. Its syntax is:
205
Public Overridable Property Anchor As System.Windows.Forms.AnchorStyles The AnchorStyles type is an enumeration that defines the values
Left ,
Top ,
Right ,
Bottom , and
None . To anchor a control on more than one edge, combine the values with the
Or operator, as shown
here: Assumes Imports System.Windows.Forms
SomeControl.Anchor = AnchorStyles.Top Or AnchorStyles.Right By default, controls are anchored on the top and left sides. This means that if a form is resized, its
controls maintain a constant distance from the top and left edges of the form. This behavior matches the behavior of Visual Basic 6 forms.
For example, Figur e 5- 6
shows a common button configuration, where the OK and Cancel buttons should track the right edge of the form as the form is resized. In previous versions of Visual Basic, it
was necessary to add code to the forms Resize event handler to reposition the buttons as the form was resized. In Visual Basic .NET, however, it is necessary only to set the buttons Anchor property
appropriately. This can be done either in Visual Studio .NETs Properties window or in code in the forms constructor.
Figure 5-6. A sizable form with controls that should be anchored on the top and right edges
The code to anchor a button on the top and right edges looks like this: Assumes Imports System.Windows.Forms
btnOk.Anchor = AnchorStyles.Top Or AnchorStyles.Right Sometimes a control should stretch as the form is resized. This is accomplished by anchoring the
control to two opposite sides of the form. For example, the text box in Figur e 5- 7
should always fill the space between the left edge of the form and the OK button on the right side of the form.
Figure 5-7. In this form, the text box should expand and shrink to fill the available space
To accomplish this, lay out the form as shown, anchor the buttons on the top and right edges as already discussed, then anchor the text box on the top, left, and right edges. By default, the label in
the form is already anchored on the top and left edges. The code looks like this:
Assumes Imports System.Windows.Forms
206
Anchor the OK and Cancel buttons on the top and right edges. btnOk.Anchor = AnchorStyles.Top Or AnchorStyles.Right
btnCancel.Anchor = AnchorStyles.Top Or AnchorStyles.Right Anchor the Filename text box on the top, left, and right edges.
This causes the text box to resize itself as needed. txtFilename.Anchor = AnchorStyles.Top Or AnchorStyles.Left _
Or AnchorStyles.Right
5.3.2 The Dock Property