Controls


The controls included in Windows Forms provide basic functionality for a wide range of applications. The controls in Windows Forms 2.0 are very similar to those in previous versions of Windows Forms, but there are some significant differences to the controls in VB6. This section covers the features that all controls use (such as docking) and summarizes the standard controls available to you. Important changes from pre-.NET versions of Visual Basic (VB6 and earlier) are briefly mentioned.

Control Tab Order

The VS2005 design environment enables you to set the tab order of the controls on a form simply by clicking them in sequence. To activate the feature, open a form in the designer and select View image from book Tab Order. This will result in a small number in the upper-left corner of each control on your form, representing the tab index of that control.

To set the values, simply click on each control in the sequence you want the tab flow to operate. The screen shot in Figure 15-5 shows a simple form with the tab order feature enabled.

image from book
Figure 15-5

Tip 

In Windows Forms 2.0, it is possible to have two or more controls with the same tab index value. At runtime, Visual Basic will break the tie by using the z-order of the controls. The control that is highest in the z-order receives the focus first. The z-order is a ranking number that determines which controls are in front of or behind other controls. (The term comes from the z-axis, which is an axis perpendicular to the traditional x- and y-axes.) The z-order can be changed by right-clicking the control and selecting Bring to Front.

Dynamic Sizing and Positioning of Controls

Windows Forms 2.0 includes a variety of ways to allow user interfaces to be dynamic. Controls can be set to automatically stretch and reposition themselves as a form is resized. Controls can also be dynamically arranged inside some special container controls intended for that purpose. This section covers all these ways of allowing dynamic sizing and positioning of controls.

Docking

Docking refers to gluing a control to the edge of a parent control. Good examples of docked controls are menu bars and status bars, which are typically docked to the top and bottom of a form, respectively. All visual controls have a Dock property.

To work through an example, create a new Windows application and place a Textbox on a form. Set the Text property of the TextBox to I’m Getting Docked. The result when you show the form should look something like Figure 15-6.

image from book
Figure 15-6

Suppose that you need to glue this TextBox to the top of the form. To do this, view the Dock property of the label. If you pull it down, you’ll see a small graphic like the one shown in Figure 15-7.

image from book
Figure 15-7

Simply click the top section of the graphic to stick the label to the top of the form. The other sections give you other effects. (A status bar would use the bottom section, for example. Clicking the box in the middle causes the control to fill the form.) The TextBox control will immediately “stick” to the top of your form. When you run your program and stretch the window sideways, you’ll see the effect shown in Figure 15-8.

image from book
Figure 15-8

Important 

If you attempt to dock multiple controls to the same edge, Windows Forms must decide how to break the tie. Precedence is given to controls in reverse z-order. In other words, the control that is furthest back in the z-order will be the first control next to the edge. If you dock two controls to the same edge and want to switch them, then right-click the control you want docked first and select Send to Back.

If you want a gap between the edge of your form and the docked controls, set the DockPadding property of the parent control. You can set a different value for each of the four directions (Left, Right, Top, Bottom). You can also set all four properties to the same value using the All setting.

Anchoring

Anchoring is similar to docking except that you can specifically define the distance that each edge of your control will maintain from the edges of a parent. To see it in action, add a button to the form in the docking example. The result should look like Figure 15-9.

image from book
Figure 15-9

Dropping down the Anchor property of the button gives you the graphic shown in Figure 15-10.

image from book
Figure 15-10

The four rectangles surrounding the center box enable you to toggle the anchor settings of the control. Figure 15-10 shows the default anchor setting of Top, Left for all controls.

When the setting is on (dark gray), the edge of the control maintains its starting distance from the edge of the parent as the parent is resized. If you set the anchor to two opposing edges (such as the left and right edges), the control stretches to accommodate this, as shown in Figure 15-11.

image from book
Figure 15-11

One of the most common uses of anchoring is to set the Anchor property for buttons in the lower-right portion of a form. Setting the Anchor property of a button to Bottom, Right causes the button to maintain a constant distance to the bottom-right corner of the form.

You can also set the Anchor property in code. The most common scenario for this would be for a control created on-the-fly. To set the Anchor property in code, you must add together the anchor styles for all the sides to which you need to anchor. For example, setting the Anchor property to Bottom, Left would require a line of code like this:

 MyControl.Anchor = Ctype(AnchorStyles.Bottom + AnchorStyles.Right, AnchorStyles)

Sizable Containers

Previous versions of Windows Forms used the Splitter control to allow resizing of containers. This control is still available in Windows Forms 2.0, but does not appear by default in the Toolbox. In its place is a replacement control, SplitContainer, that provides the same functionality with less work on your part.

A single SplitContainer acts much like two panels with an appropriately inserted Splitter. You can think of it as a panel with two sections, with the divider between the sections movable so that the relative sizes of the sections can be changed by a user.

To use a SplitContainer, simply drop it on a form, resize it, and position the draggable divider to the appropriate point. If you want the divider to be horizontal instead of vertical, you change the Orientation property. Then you can place controls in each subpanel in any way you like. It is common to insert a control such as a TreeView or ListBox, and then dock it to its respective subpanel. This makes such contained controls resizable by the user. A typical example of a SplitContainer in action is shown in Figure 15-12.

image from book
Figure 15-12

The cursor in Figure 15-12 shows that the mouse is hovering over the divider, allowing repositioning of the divider by dragging the mouse. A SplitContainer may be nested inside another SplitContainer. This enables you to build forms in which several parts are resizable relative to each other.

FlowLayoutPanel Control

The summary of new features mentioned a new control for Windows Forms 2.0 called the FlowLayout - Panel control. This control allows dynamic layout of controls contained within the FlowLayoutPanel, based on the size of the FlowLayoutPanel.

FlowLayoutPanel works conceptually much like a simple HTML page shown in a browser. The controls that are placed in the FlowLayoutPanel are positioned in sequence horizontally until there’s not enough space for the next control, which then wraps further down for another row of controls. The following walkthrough demonstrates this capability.

Start a new Windows application project. On the blank Form1 included in the new project, place a FlowLayoutPanel control toward the top of the form, and make it a bit less wide than the width of the form. Set the Anchor property for the FlowLayoutPanel to Top, Left, and Right. Set the BorderStyle property for the FlowLayoutPanel to FixedSingle so it’s easy to see.

Place three Button controls in the FlowLayoutPanel, keeping their default sizes. The form you create should look like the one shown in Figure 15-13.

image from book
Figure 15-13

Run the application. The initial layout will be similar to the design-time layout. However, if you resize the form to about two thirds of its original width, the layout of the buttons changes. Because there is no longer enough room for them to be arranged side by side, the arrangement automatically switches. Figure 15-14 shows the form in three configurations: first with its original width, then narrower so that only two buttons fit in the FlowLayoutPanel, and finally so narrow that the buttons are all stacked in the FlowLayoutPanel.

image from book
Figure 15-14

Note that no logic of any kind was added to the form - the FlowLayoutPanel handles the repositioning of the buttons automatically. In fact, any position information you set for the button controls is ignored if they are placed in a FlowLayoutPanel.

Padding and Margin Properties

To assist in positioning controls in the FlowLayoutPanel, all controls have a new property called Margin. There are settings for Margin.Left, Margin.Right, Margin.Top, and Margin.Bottom. These settings determine how much space is reserved around a control when calculating its automatic position in a FlowLayoutPanel.

You can see the Margin property in action by changing the Margin property for one or more of the buttons in the previous example. If you change all the Margin settings for the first Button to 10 pixels, for example, and run the application, the form will look like the one shown in Figure 15-15.

image from book
Figure 15-15

The first button now has a 10-pixel separation from all the other controls in the FlowLayoutPanel, as well as a 10-pixel separation from the edges of the FlowLayoutPanel itself.

The Padding property is for the FlowLayoutPanel or other container control. When a control is embedded into a FlowLayoutPanel, the Padding.Left, Padding.Right, Padding.Top, and Padding.Bottom properties of the FlowLayoutPanel determine how far away from the inside edge of the container to position the control.

You can see the Padding property in action by changing the Padding property for the FlowLayout - Panel in the previous example. If you set all Padding settings to 20 pixels, and reset the Margin property for the first Button back to the default, then the form will look like Figure 15-16 in the visual designer.

image from book
Figure 15-16

Notice that all the controls in the FlowLayoutPanel are now at least 20 pixels from the edges.

The Padding property is also applicable to other container controls, if the contained controls have their Dock property set. If the settings for Padding are not zero, a docked control will be offset from the edge of the container by the amount specified by the Padding property.

TableLayoutPanel Control

The other new control for dynamic layout is the TableLayoutPanel. This control consists of a table of rows and columns, resulting in a rectangular array of cells. You can place one control in each cell. However, that control can itself be a container, such as a Panel or FlowLayoutPanel.

The dimensions of the columns and rows can be controlled by setting some key properties. For columns, set the number of columns with the ColumnCount property, and then control each individual column with the ColumnStyles collection. When you click on the button for the ColumnStyles collection, you’ll get a designer window that enables you to set two key properties for each column - SizeType and Width.

SizeType can be set to one of the following enumerations:

  • Absolute - Sets the column width to a fixed size in pixels

  • AutoSize - Indicates that the size of the column should be managed by the TableLayoutPanel, which allocates width to the column depending on the widest control contained in the column

  • Percent - Sets the percentage of the TableLayoutPanel to use for the width of the column

The Width property is only applicable if you do not choose a SizeType of AutoSize. It sets either the number of pixels for the width of the column (if the SizeType is Absolute) or the percentage width for the column (if the SizeType is set to Percent).

Similarly, for rows, there is a RowCount property to set the number of rows, and a RowStyles collection to manage the size of the rows. Each row in RowStyles has a SizeType, which works the same way as SizeType does for Columns except that it manages the height of the row instead of the width of a column. The Height property is used for rows instead of a Width property, but it works in a corresponding way. Height is either the number of pixels (if SizeType is Absolute) or a percentage of the height of the TableLayoutPanel (if SizeType is Percent). If SizeType is AutoSize, then a row is sized to the height of the tallest control in the row.

An advanced UI layout technique is to first create a TableLayoutPanel, and then embed a Flow - LayoutPanel in some of the cells of the TableLayoutPanel. This allows several controls to be contained in a cell and repositioned as the size of the cell changes.

A step-by-step example of using a TableLayoutPanel, with an embedded FlowLayoutPanel, is included in the next chapter in the section “Creating a Composite UserControl.”

Panel and GroupBox Container Controls

Of course, not all applications need the dynamic layout of the containers just discussed. Windows Forms includes two controls that are static containers, in which the positions and layout of the contained controls are not adjusted at all.

In VB6, the Frame control was used for this purpose. However, Windows Forms has two such containers, with minor differences between them: the GroupBox control and the Panel control.

These two are similar in the following ways:

  • They can serve as a container for other controls.

  • If they are hidden or moved, then the action affects all the controls in the container.

The GroupBox control is the one that most closely resembles an old VB6 Frame control visually. It acts much like a VB6 Frame control too, with one significant exception: There is no way to remove its border. It always has a border, and it can have a title, if needed. The border is always set the same way. Figure 15-17 shows a form with a GroupBox control containing three RadioButtons.

image from book
Figure 15-17

The Panel control has three major differences from GroupBox:

  • It has options for displaying its border in the BorderStyle property, with a default of no border.

  • It has the capability to scroll if its AutoScroll property is set to True.

  • It cannot set a title or caption.

Figure 15-18 shows a form containing a Panel control with its BorderStyle property set to FixedSingle, with scrolling turned on by setting AutoScroll to True, and with a CheckedListBox that is too big to display all at once (which forces the Panel to show a scrollbar).

image from book
Figure 15-18

Extender Providers

There is a new family of components in Windows Forms that can only be used in association with visual controls. These components are known as extender providers. They work with the Visual Studio IDE to cause new properties to appear in the Properties window for controls on the form.

Extender providers have no visible manifestation except in conjunction with other controls, so they appear in the component tray. The three extender providers available with Windows Forms 2.0 are the HelpProvider, the ToolTip, and the ErrorProvider. All three work in basically the same way. Each extender provider implements the properties that are “attached” to other controls. The best way to see how this works is to go through an example, so let’s do that with a ToolTip component.

ToolTip

The ToolTip is the simplest of the built-in extender providers. It adds just one property to each control, named ToolTip on ToolTip1 (assuming the ToolTip control has the default name of ToolTip1). This property works very much the same way the ToolTipText property works in VB6, and in fact replaces it.

To see this in action, create a Windows Forms application. On the blank Form1 that is created for the project, place a couple of buttons. Take a look at the Properties window for Button1. Notice that it does not have a ToolTip property of any kind.

Drag over the ToolTip control, which will be placed in the component tray. Go back to the Properties window for Button1. A property named ToolTip on ToolTip1 is now present. Set any string value you like for this property.

Run the project and hover the mouse pointer over Button1. You will see a tooltip containing the string value you entered for the ToolTip on ToolTip1 property.

Other properties of the ToolTip component enable you to control other characteristics of the tooltip, such as the initial delay before the tooltip appears.

New in Windows Forms 2.0 is the capability to change the shape of tooltips to a “balloon.” This is done by setting the IsBalloon property of the Tooltip component to True. Instead of a hovering rectangular tooltip, the tooltip has a rounded rectangular outline with a pointer to the control it is associated with, not unlike the dialog balloons in a comic strip. Figure 15-19 shows an example.

image from book
Figure 15-19

HelpProvider

The HelpProvider enables controls to have associated context-sensitive help available by pressing F1. When a HelpProvider is added to a form, all controls on the form get these new properties, which show up in the controls’ Properties window.

Property

Usage

HelpString on

HelpProvider1

Provides a pop-up tooltip for the control when F1 is pressed while the control has the focus. If the HelpKeyword and HelpNavigator properties (see later) are set to provide a valid reference to a help file, then the HelpString value is ignored in favor of the information in the help file.

HelpKeyword on

HelpProvider1

Provides a keyword or other index to use in a help file for context-sensitive help for this control. The HelpProvider1 control has a property that indicates the help file to use. This replaces the HelpContextID property in VB6.

HelpNavigator on

HelpProvider1

Contains an enumerated value that determines how the value in HelpKeyword is used to refer to the help file. There are several possible values for displaying such elements as a topic, an index, or a table of contents in the help file.

ShowHelp on

HelpProvider1

Determines whether the HelpProvider control is active for this control

Filling in the HelpString property immediately causes the control to provide tooltip help when F1 is pressed while the control has the focus. The HelpProvider control has a property to point to a help file (either an HTML help file or a Win32 help file), and the help topic in the HelpTopic property points to a topic in this file.

ErrorProvider

The ErrorProvider component presents a simple, visual way to indicate to a user that a control on a form has an error associated with it. The added property for controls on the form when an ErrorProvider is used is called Error on ErrorProvider1 (assuming the ErrorProvider has the default name of ErrorProvider1). Setting this property to a string value causes the error icon to appear next to a control, and for the text to appear in a tooltip if the mouse hovers over the error icon.

Figure 15-20 shows a screen with several text boxes, and an error icon next to one (with a tooltip). The error icon and tooltip are displayed and managed by an ErrorProvider.

image from book
Figure 15-20

The ErrorProvider component’s default icon is a red circle with an exclamation point. When the Error property for the text box is set, the icon blinks for a few moments, and hovering over the icon causes the tooltip to appear. Writing your own code to set the Error property is explained in the section “Working with Extender Providers in Code.”

Properties of Extender Providers

In addition to providing other controls with properties, extender providers also have properties of their own. For example, the ErrorProvider has a property named BlinkStyle. When it is set to NeverBlink, the blinking of the icon is stopped for all controls that are affected by the ErrorProvider.

Other properties of the ErrorProvider enable you to change things such as the icon used and where the icon appears in relation to the field containing the error. For instance, you might want the icon to appear on the left side of a field instead of the default right side. You can also have multiple error providers on your form. For example, you may wish to give users a warning, rather than an error. A second error provider with a yellow icon could be used to provide this feature.

Working with Extender Providers in Code

Setting the Error property in the previous example can be done with the Properties window, but this is not very useful for on-the-fly error management. However, setting the Error property in code is not done with typical property syntax. By convention, extender providers have a method for each extended property they need to set, and the arguments for the method include the associated control and the property setting. To set the Error property in the previous example, the following code was used:

  ErrorProvider1.SetError(txtName, "You must provide a location!") 

The name of the method to set a property is the word Set prefixed to the name of the property. This line of code shows that the Error property is set with the SetError method of the ErrorProvider.

There is a corresponding method to get the value of the property, and it is named with Get prefixed to the name of the property. To determine the current Error property setting for txtName, you would use the following line:

  sError = ErrorProvider1.GetError(txtName) 

Similar syntax is used to manipulate any of the properties managed by an extender provider. The discussion of the tooltip provider earlier mentioned setting the tooltip property in the Properties window. To set that same property in code, the syntax would be as follows:

  ToolTip1.SetToolTip(Button1, "New tooltip for Button1") 

Advanced Capabilities for Data Entry

New for Windows Forms 2.0 are a couple of advanced capabilities for data entry. Textbox and Combobox controls now have autocompletion capabilities, and a new MaskedTextbox allows entry of formatted input such as phone numbers.

Autocompletion

Responsive user interfaces help users accomplish their purposes, thereby making them more productive. One classic way to do this is with autocompletion.

An example of autocompletion is IntelliSense in Visual Studio. Using IntelliSense, the user only has to type in a few letters, and Visual Studio presents a list of probable entries matching those letters. If the desired entry is found, the user only needs to select it, rather than type the entire entry.

Autocompletion is available in Windows Forms 2.0 with text boxes and combo boxes. Both use a set of properties to control how autocompletion works and from where the list of entries available to the user comes.

To see autocompletion in action, create a Windows application project. Drag a Textbox from the toolbox onto the blank Form1 created for the project. Set the AutoCompleteMode for the text box to Suggest in the Properties window. Then set the AutoCompleteSource to CustomSource. Finally, click the button in the setting window for AutoCompleteCustomSource. You’ll see a window for adding entries that is very similar to the window for entering items for a list box or combo box.

Enter the following items into the dialog:

 Holder Holland Hollis Holloway Holly Holstein Holt

Start the project and type Hol into the text box. As soon as you start typing, a drop-down will appear that contains entries matching what you’ve typed, including all seven elements in the list. If you then type another 1, the list will decrease to four elements that begin with Holl. If you then type an o, the list will contain only the entry Holloway.

The AutoCompleteMode has two other modes. The Append mode does not automatically present a drop-down, but instead appends the rest of the closest matching entry to the text in the Textbox or ComboBox, and highlights the untyped characters. This allows the closest matching entry to be placed in the text area without the user explicitly selecting an entry.

The SuggestAppend mode combines Suggest and Append. The current best match is displayed in the text area, and the drop-down with other possibilities is automatically displayed. This mode is the one most like IntelliSense.

You can also set the list of items to be included in the autocompletion list at runtime, which is the most common usage scenario. A list of items from a database table would typically be loaded for autocompletion. Here is typical code to create a list of items and attach the list to a combo box:

 Dim nReturn As Integer nReturn = autoCompleteStringCollection1.Add("Holder") nReturn = autoCompleteStringCollection1.Add("Holland") nReturn = autoCompleteStringCollection1.Add("Hollis") nReturn = autoCompleteStringCollection1.Add("Holloway")

ComboBox1.AutoCompleteCustomSource = autoCompleteStringCollection1

For this sample to work properly, the Combobox control’s AutoCompleteSource property must be set to CustomSource.

Several built-in lists are available to use for autocompletion. Instead of setting AutoCompleteSource to CustomSource, you can set it to sources such as files in the file system, or URLs recently used in Internet Explorer. See the documentation for AutoCompleteSource for additional options; or, if you are using AutoCompleteSource in code, IntelliSense will show the options available.

MaskedTextbox Control

The new features summary discussed the addition of a MaskedTextbox control, which fills in for the old VB6 MaskedEdit control. If you have used MaskedEdit in VB6, the MaskedTextbox will feel quite familiar.

After dragging a MaskedTextbox control to a form, you typically want to first set the mask associated with the control. You can do this in the Properties window by selecting the Mask property, but you can also click the smart tag (right-pointing arrow) on the right side of the MaskedTextbox. In either case, you can either construct a mask manually or select one of the commonly used masks from a list.

If you need to create your own mask, you need to design it based on a set of formatting characters:

Open table as spreadsheet

Mask Character

Description

#

Digit placeholder

.

Decimal placeholder. The actual character used is the one specified as the decimal placeholder in your international settings. This character is treated as a lite ral for masking purposes.

,

Thousands separator. The actual character used is the one specified as the thousands separator in your international settings. This character is treated as a literal for masking purposes.

:

Time separator. The actual character used is the one specified as the time separator in your international settings. This character is treated as a literal for masking purposes.

/

Date separator. The actual character used is the one specified as the date separator in your international settings. This character is treated as a literal for masking purposes.

\

Treat the next character in the mask string as a literal. This allows you to include the #, &, A, and ? characters in the mask. This character is treated as a literal for masking purposes.

&

Character placeholder. Valid values for this placeholder are ANSI characters in the following ranges: 32126 and 128255.

>

Converts all the characters that follow to uppercase

<

Converts all the characters that follow to lowercase

A

Alphanumeric character placeholder (entry required). For example: az, AZ, or 09.

a

Alphanumeric character placeholder (entry optional)

9

Digit placeholder (entry optional). For example: 09.

C

Character or space placeholder (entry optional). This operates exactly like the & placeholder and ensures compatibility with Microsoft Access.

?

Letter placeholder. For example: az or AZ.

Literal

All other symbols are displayed as literals - that is, as themselves.

Literal characters are simply inserted automatically by the MaskedTextbox control. If you have literal characters for the parentheses in a phone number, for example, the user need not type these in order for them to show up in the text area of the control.

As an example of a mask, suppose that you have an account number that must consist of exactly two uppercase letters and five digits. You could construct a mask of >??00000. The first character forces all letters to uppercase. The two question marks specify two required alphabetic characters, and the five zeros specify five required digits.

Once you have set the Mask for the MaskedTextbox, all entries into the control will be coerced to the Mask pattern. Keystrokes that don’t conform will be thrown away.

Validating Data Entry

Most controls that you place on a form require that its content be validated in some way. A text box might require a numeric value only or simply require that the user provide any value and not leave it blank.

The ErrorProvider component discussed earlier makes this task significantly easier than it was in previous versions. To illustrate the use of an ErrorProvider in data validation, create a new Windows application project and change the Text property for the blank Form1 to Data Validation Demo. Then place two text boxes on the form that will hold a user ID and password, as shown in Figure 15-21.

image from book
Figure 15-21

Name the first text box UserNameTextBox and name the second text box PasswordTextBox. Drag an ErrorProvider onto the form, which will cause it to appear in the component tray. In the next section, you’ll add the code that simply verifies that the user has filled in both text boxes and gives a visual indication, via the ErrorProvider, if either of the fields has been left blank.

The Validating Event

The Validating event fires when your control begins its validation. It is here that you need to place the code that validates your control, and set a visual indication for the error. Insert the following code to see this in action:

  Private Sub UserNameTextBox_Validating(ByVal sender As Object, _                             ByVal e As System.ComponentModel.CancelEventArgs) _                             Handles UserNameTextBox.Validating     If userNameTextbox.Text = "" Then         ErrorProvider1.SetError(UserNameTextBox, "User Name cannot be blank")     Else         ErrorProvider1.SetError(UserNameTextBox, "")     End If End Sub Private Sub PasswordTextBox_Validating(ByVal sender As Object, _                             ByVal e As System.ComponentModel.CancelEventArgs) _                             Handles PasswordTextBox.Validating     If passwordTextbox.Text = "" Then         ErrorProvider1.SetError(PasswordTextBox, "Password cannot be blank")     Else         ErrorProvider1.SetError(PasswordTextBox, "")     End If End Sub 

Run the program and then tab between the controls without entering any text to get the error message. You’ll see an icon blink next to each of the text box controls; and if you hover over an error icon, you’ll see the appropriate error message.

There is also a Validated event that fires after a control’s Validating event. It can be used, for example, to do a final check after other events have manipulated the contents of the control.

The CausesValidation Property

The CausesValidation property determines whether the control will participate in the validation events on the form. A control with a CausesValidation setting of True (it is True by default) has two effects:

  • The control’s Validating/Validated events fire when appropriate.

  • The control triggers the Validating/Validated events for other controls.

It is important to understand that the validation events fire for a control not when the focus is lost but when the focus shifts to a control that has a CausesValidation value of True.

To see this effect, set the CausesValidation property of the password text box in your application to False (be sure to leave it True for the user ID and OK button). When you run the program, tab off the user ID text box and again to the OK button. Notice that it isn’t until the focus reaches the OK button that the validating event of the user ID text box fires. Also notice that the validating event of the Password field never fires.

Ultimately, if you determine that the control is not valid, you need to specify what happens. That may include setting the focus to the control that needs attention (as well as indicating the error with an ErrorProvider).

Toolbars and the New ToolStrip Control

As mentioned in the summary of new features in Windows Forms 2.0, the ToolStrip control replaces the Toolbar control from Windows Forms 1.0 and 1.1. ToolStrip has many improvements. It supports movement to sides of a form other than the place where it was laid out, and you have much more flexibility in placing items on the toolbar. It also integrates better with the IDE to assist in creating toolbars and manipulating the many settings available.

The ToolStrip does not sit alone on a form. When a ToolStrip is dragged onto a form, the container that actually sits on the form is called a RaftingContainer. This container handles the positioning so that the toolbar created by a ToolStrip can be dragged to other parts of the form.

The ToolStrip sits inside the RaftingContainer and is the container for toolbar elements. It handles the sizing of the toolbar, movement of toolbar elements, and other general toolbar functions.

The items on the toolbar must be from a set of controls specially designed to serve as toolbar items. All of these items inherit from the ToolStripItem base class. The controls available for toolbar items are as follows:

Open table as spreadsheet

Control

Description

ToolStripButton

Replicates the functionality of a regular Button for a toolbar

ToolStripLabel

Replicates the functionality of a regular Label for a toolbar

ToolStripSeparator

A visual toolbar element that displays a vertical bar to separate other groups of elements (no user interaction)

ToolStripComboBox

Replicates the functionality of a regular ComboBox for a toolbar. This item must be contained within a ToolStripControlHost (see below).

ToolStripTextBox

Replicates the functionality of a regular TextBox for a toolbar. This item must be contained within a ToolStripControlHost (see below).

ToolStripControlHost

A hosting container for other controls that reside on a ToolStrip. It can host any of the following controls: ToolStripComboBox, ToolStripTextBox, other Windows Forms controls, or user controls.

ToolStripDropDownItem

A hosting container for toolbar elements that feature drop-down functionality. Can host a ToolStripMenuItem, a ToolStripSplitButton, or a ToolStripDropDownButton.

ToolStripDropDownButton

A button that supports drop-down functionality. Clicking the button shows a list of options, and the user must then click the one desired. This item is used when the user needs to select from a group of options, none of which is used a large majority of the time.

ToolStripSplitButton

A combination of a regular button and a drop-down button. This item is often used when there is a frequently used option to click, but you also need to offer the user other options that are less frequently used.

ToolStripMenuItem

A selectable option displayed on a menu or context menu. This item is typically used with the menu controls that inherit from the ToolStrip, discussed later in this chapter in the section “Menus.”

Note that almost any control can be hosted on a toolbar using the ToolStripControlHost. However, for buttons, text boxes, labels, and combo boxes, it is much easier to use the ToolStrip version instead of the standard version.

Creating a ToolStrip and Adding Toolbar Elements

Try an example to see how to build a toolbar using the ToolStrip control. Create a new Windows application. Add a ToolStrip control to the blank Form1 that is included with the new project. Make the form about twice its default width so that you have plenty of room to see the ToolStrip as you work on it.

The ToolStrip is positioned at the top of the form by default. It does not contain any elements, although if you highlight the ToolStrip control in the component tray, a “menu designer” will appear in the ToolStrip.

The easiest way to add multiple elements to the ToolStrip is to use the designer dialog for the ToolStrip. Highlight the ToolStrip in the component tray and click the button in the Properties window for the Items property. You’ll see a designer dialog like the one shown in Figure 15-22.

image from book
Figure 15-22

The drop-down in the upper-left corner contains the different types of items that can be placed on the toolbar. The names in the drop-down are the same as the ones in the table of controls except that the “Toolstrip” prefix is not present. Add one each of the following types, with the setting specified:

  • Button - Set the Text property to Go. Set the Display property to Text.

  • ComboBox - Leave the Text property blank. Set DropDownStyle to DropDownList. Open the Items dialog and add the names of some colors.

  • SplitButton - Set the Text property to Options. Set the Display property to Text.

  • TextBox - Leave the Text property blank.

Click OK. The ToolStrip will look like the one shown in Figure 15-23.

image from book
Figure 15-23

You can now handle events on any of these toolbar elements the same way you would any other controls. You can double-click to get a Click event routine or access the event routines through the dropdowns in the Code Editor.

To make the Toolstrip more dynamic, it must be embedded in a ToolStripContainer. You can do that manually by dragging one over and putting the Toolstrip in it, but the easy way to do it is to click the smart tag on the Toolstrip and then select Embed in ToolStripContainer. This causes a ToolStripContainer to appear on your form. Set the Dock property for the ToolStripContainer to Fill and it will provide a surface for the Toolstrip that includes all four edges of the form.

Run your program. Using the mouse, grab the dotted handle on the far left edge of the toolbar. If you drag this to the right, the toolbar will be repositioned. If you drag it to other positions on the form, then the entire toolbar will dock to different edges of the form.

Allowing the User to Move Toolbar Elements

By default, the AllowItemReorder property of the ToolStrip is set to False. If you change that to True, then the elements on the toolbar can be moved around in relation to one another (reordered) at runtime.

Change the AllowItemReorder property to True for the ToolStrip and run your program again. Hold down the Alt key and drag elements on the toolbar around. They will assume new positions on the toolbar when you drop them.

Creating a Standard Set of Toolbar Elements

If you need a toolbar that has the typical visual elements for cut, copy, paste, and so on, it is not necessary to create the elements. The designer will do it for you.

Create a new form in your project and drag a ToolStrip onto it. As before, it will be positioned at the top and will not contain any elements.

With the ToolStrip highlighted in the component tray, click the Item property. Below the properties in the Properties window, a link named Insert Standard Items will appear. Click that link; elements will be inserted into the ToolStrip, making it look like the one in Figure 15-24.

image from book
Figure 15-24

Menus

Menus are added to a form in VB.NET 2005 by dragging controls called MenuStrip or ContextMenuStrip onto your form. MenuStrip implements a standard Windows-style menu at the top of the form. ContextMenuStrip allows a pop-up menu with a right mouse button click.

These controls are actually subclasses of the ToolStrip, so much of the information you learned earlier in this chapter about working with the ToolStrip also applies to the MenuStrip and ContextMenuStrip. When dragged onto the form, these controls appear in the component tray just as the ToolStrip does, and you access the designer for these controls the same way you do for the ToolStrip. However, because these are menus, the most common way of adding items is to type items directly into the menu designer that appears when the control is highlighted.

The menu designer is extremely intuitive - the menu appears on your form just as it would at runtime, and you simply fill in the menu items you need. Each item can be renamed, and each can have a Click event associated with it.

Adding Standard Items to a Menu

If your form’s menu needs to have the standard top-level options (File, Edit, and so on) and the typical options under these items, then you can have all these typical options inserted for you automatically.

To see this capability in action, drag a MenuStrip to a form and then click the smart tag (the right arrow at the right edge) for the MenuStrip to bring up the designer dialog. Click the link at the bottom of the dialog that says Insert Standard Items.

Icons and Checkmarks for Menu Items

Each menu item has an Image property. Setting this property to an image causes the image to appear on the left side of the text for the menu option. You can see this property in use by looking at the standard items inserted in the preceding example. The File image from book Save option has an icon of a diskette, which is produced by setting the image property of that item.

Items can also have check marks beside them. This is done by changing the Checked property of the item to True. You can do this at design time or runtime, enabling you to manipulate the check marks on menus as necessary.

Context Menus

To implement a context menu for a form or any control on a form, drag a ContextMenuStrip to the form and add the menu items. Items are added and changed the same way as they are with the MenuStrip.

To hook a context menu to a control, set the control’s ContextMenuStrip property to the ContextMenuStrip menu control you want to use. Then, when your program runs and you rightclick in the control, the context menu will pop up.

Dynamically Manipulating Menus at Runtime

Menus can be adjusted at runtime using code. Context menus, for instance, may need to vary depending on the state of your form. The following walkthrough shows how to add a new menu item to a context menu and how to clear the menu items.

Create a new Windows application. On the blank Form1 for the project, drag over a MenuStrip control. Using the menu designer, type in a top-level menu option of File. Under that option, type in options for Open and Save.

Now place a button on the form. Double-click the button to get its Click event, and place the following code into the event:

  Dim NewItem As New ToolStripMenuItem NewItem.Text = "Save As" ' Set any other properties of the menu item you like. FileToolStripMenuItem.DropDownItems.Add(NewItem) AddHandler NewItem.Click, _      AddressOf Me.NewMenuItem_Click 

Add the event handler referenced in this code at the bottom of the form’s code:

  Private Sub NewMenuItem_Click(ByVal sender As System.Object, _                               ByVal e As System.EventArgs)    MessageBox.Show("New menu item clicked!") End Sub 

If you now run the program and look at the menu, it will only have File and Save options. Clicking the button will cause a new Save As item to be added to the menu, and it will be hooked to the event routine called NewMenuItem_Click.

Common Dialogs

Windows Forms provides you with seven common dialog controls. Each is a control that opens a predefined form that is identical to the one used by the operating system.

These dialogs cannot be shown modeless. They have a ShowDialog method to show them modally. That method returns one of the standard DialogResult values, as discussed in the section “Dialogs” earlier in this chapter.

OpenFileDialog and SaveFileDialog

These two controls open the standard dialog control that allows a user to select files on the system. They are quite similar except for the buttons and labels that appear on the actual dialog box when it is shown to the user. Each prompts the user for a file on the system by allowing the user to browse the files and folders available.

Use the following properties to set up the dialog boxes:

Open table as spreadsheet

Property

Comments

InitialDirectory

Defines the initial location that is displayed when the dialog opens. For example,

 OpenFileDialog1.InitialDirectory =  "C:\Program Files"

Filter

String that defines the Files of Type list. Separate items using the pipe chara cter. Items are entered in pairs; the first of each pair is the description of the file type, and the second half is the file wildcard. For example:

 OpenFileDialog1.Filter = "All Files$|*.* |Text Files|*.txt|Rich Text Files|*.rtf"

FilterIndex

Integer that specifies the default filter item to use when the dialog box opens. For example, with the preceding filter used, default to text files as follows:

 OpenFileDialog1.FilterIndex = 2

RestoreDirectory

Boolean value that, when True, forces the system’s default directory to be restored to the location it was in when the dialog box was first opened. This is False by default.

Filename

Holds the full name of the file that the user selected, including the path

ShowDialog()

Displays the dialog

The following code opens the standard dialog box, asking the user to select a file that currently exists on the system, and simply displays the choice in a message box upon return:

  OpenFileDialog1.InitialDirectory = "C:\" OpenFileDialog1.Filter = "Text files|*.txt|All files|*.*" OpenFileDialog1.FilterIndex = 1 OpenFileDialog1.RestoreDirectory = True If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then     MessageBox.Show("You selected """ & OpenFileDialog1.FileName & """") End If 

ColorDialog Control

As the name implies, this control gives the user a dialog box from which to select a color. Use the following properties to set up the dialog boxes as follows:

  ColorDialog1.Color = TextBox1.BackColor ColorDialog1.AllowFullOpen = True If ColorDialog1.ShowDialog()= Windows.Forms.DialogResult.OK Then     TextBox1.BackColor = ColorDialog1.Color End If 

Open table as spreadsheet

Property

Comments

Color

The System.Drawing.Color that the user selected. You can also use this to set the initial color selected when the user opens the dialog.

AllowFullOpen

Boolean value that, when True, allows the user to select any color. If False, the user is restricted to the set of default colors.

ShowDialog()

Displays the dialog

FontDialog Control

This control displays the standard dialog box, allowing a user to select a font. Use the following properties to set up the dialog boxes:

Using these properties looks like this:

Open table as spreadsheet

Property

Comments

Font

The System.Drawing.Font that the user selected. Also used to set the initial font.

ShowEffects

Boolean value that, when True, makes the dialog box display the text effects options of underline and strikeout.

ShowColor

Boolean value that, when True, makes the dialog box display the combo box of the font colors. The ShowEffects property must be True for this to have an effect.

FixedPitchOnly

Boolean value that, when True, limits the list of font options to only those that have a fixed pitch (such as Courier or Lucida console).

ShowDialog()

Displays the dialog

  FontDialog1.Font = TextBox1.Font FontDialog1.ShowColor = True FontDialog1.ShowEffects = True FontDialog1.FixedPitchOnly = False If FontDialog1.ShowDialog()= Windows.Forms.DialogResult.OK Then     TextBox1.Font = FontDialog1.Font End If 

Printer Dialog Controls

There are three more common dialog controls: PrintDialog, PrintPreviewDialog, and PageSetup - Dialog. They can all be used to control the output of a file to the printer, and you can use these in conjunction with the PrintDocument component to run and control print jobs.

Drag and Drop

Implementing a drag-and-drop operation in the .NET Framework is accomplished by a short sequence of events. Typically, it begins in a MouseDown event of one control, and always ends with the DragDrop event of another.

To demonstrate the process, begin with a new Windows application. Add two list boxes to your form, and add three items to the first using the Items Property Designer. This application allows you to drag the items from one list box into the other.

The first step in making drag and drop work is specifying whether or not a control will accept a drop. By default, all controls reject such an act and do not respond to any attempt by the user to drop something onto them. In this case, set the AllowDrop property of the second list box (the one without the items added) to True.

The next item of business is to invoke the drag-and-drop operation. This is typically done in the MouseDown event of the control containing the data you want to drag (although you’re not restricted to it). The DoDragDrop method is used to start the operation. This method defines the data that will be dragged and the type of dragging that will be allowed. Here, you’ll drag the text of the selected list box item, and permit both a move and a copy of the data to occur.

Switch over to the code window of your form and add the following code to the MouseDown event of ListBox1:

  Private Sub ListBox1_MouseDown(ByVal sender As Object, _                               ByVal e As System.Windows.Forms.MouseEventArgs) _                                Handles ListBox1.MouseDown    Dim DragDropResult As DragDropEffects    If e.Button = MouseButtons.Left Then       DragDropResult = ListBox1.DoDragDrop( _                     ListBox1.Items(ListBox1.SelectedIndex), _                     DragDropEffects.Move Or DragDropEffects.Copy)        ' Leave some room here to check the result of the operation        ' (You'll fill it in next).    End If End Sub 

Notice the comment about leaving room to check the result of the operation. You’ll fill that in shortly. For now, calling the DoDragDrop method has gotten you started.

The next step involves the recipient of the data - in your case, ListBox2. Two events here are important to monitor - DragEnter and DragDrop.

As you can guess by the name, the DragEnter event occurs when the user first moves over the recipient control. The DragEnter event has a parameter of type DragEventArgs that contains an Effect property and a KeyState property.

The Effect property enables you to set the display of the drop icon for the user to indicate whether a move or a copy occurs when the mouse button is released. The KeyState property enables you to determine the state of the Ctrl, Alt, and Shift keys. It is a Windows standard that when both a move or a copy can occur, a user is to indicate the copy action by holding down the Ctrl key. Therefore, in this event, you check the KeyState property and use it to determine how to set the Effect property.

Add the following code to the DragEnter event of ListBox2:

  Private Sub ListBox2_DragEnter(ByVal sender As Object, _                                ByVal e As DragEventArgs) _                                Handles ListBox2.DragOver    If e.KeyState = 9 Then ' Control key       e.Effect = DragDropEffects.Copy    Else       e.Effect = DragDropEffects.Move    End If End Sub 

Note that you can also use the DragOver event if you want, but it will fire continuously as the mouse moves over the target control. In this situation, you only need to trap the initial entry of the mouse into the control.

The final step in the operation occurs when the user lets go of the mouse button to drop the data at its destination. This is captured by the DragDrop event. The parameter contains a property holding the data that is being dragged. It’s now a simple process of placing it into the recipient control as follows:

  Private Sub ListBox2_DragDrop(ByVal sender As Object, _                               ByVal e As System.Windows.Forms.DragEventArgs) _                               Handles ListBox2.DragDrop    ListBox2.Items.Add(e.Data.GetData(DataFormats.Text)) End Sub 

One last step: You can’t forget to manipulate ListBox1 if the drag and drop was a move. Here’s where you’ll fill in the hole you left in the MouseDown event of ListBox1. Once the DragDrop has occurred, the initial call that invoked the procedure returns a result indicating what ultimately happened. Go back to the ListBox1_MouseDown event and enhance it to remove the item from Listbox1 if it was moved (and not simply copied):

 Private Sub ListBox1_MouseDown(ByVal sender As Object, _               ByVal e As System.Windows.Forms.MouseEventArgs) _               Handles ListBox1.MouseDown     Dim DragDropResult As DragDropEffects     If e.Button = MouseButtons.Left Then        DragDropResult = ListBox1.DoDragDrop( _                      ListBox1.Items(ListBox1.SelectedIndex), _                      DragDropEffects.Move Or DragDropEffects.Copy)         ' If operation is a move (and not a copy), then remove then         ' remove the item from the first list box.         If DragDropResult = DragDropEffects.Move Then           ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)         End If     End If End Sub

When you’re done, run your application and drag the items from Listbox1 into Listbox2. Try a copy by holding down the Ctrl key when you do it. The screen shot in Figure 15-25 shows the result after Item1 has been moved and Item3 has been copied a few times.

image from book
Figure 15-25

Summary of Standard Windows.Forms Controls

Windows Forms, of course, contains most of the controls that you are accustomed to using in pre-.NET versions of Visual Basic. This section lists the basic controls that are generally quite intuitive and don’t warrant a full example to explain. Where appropriate, the important differences from pre-.NET versions of Visual Basic are stated.

  • Button

    • Known as CommandButton in VB6 and earlier

    • Now uses the Text property instead of Caption

    • Can now display both an icon and text simultaneously. The image is set using the Image property (instead of Picture). The image position can be set using the ImageAlign property (left, right, center, and so on).

    • Text on the button can be aligned using the TextAlign property.

    • Can now have different appearances using the FlatStyle property

    • No longer has the Default and Cancel properties. These are now managed by the form itself using the AcceptButton and CancelButton properties.

  • CheckBox

    • Now uses the Text property instead of Caption

    • Can now appear as a toggle button using the Appearance property

    • Check box and text can now be positioned within the defined area using the CheckAlign and TextAlign properties.

    • Uses the CheckState property instead of Value

    • Has a FlatStyle property controlling the appearance of the check box

  • CheckedListBox

    • A list box that has check boxes beside each item (see Listbox)

  • ComboBox

    • As with the new ListBox control, can now hold a collection of objects instead of an array of strings (see ListBox).

    • Now has a MaxDropDownItems property that specifies how many items to display when the list opens

  • DateTimePicker

    • Formerly known as a DTPicker

  • DomainUpDown

    • A simple one-line version of a list box

    • Can hold a collection of objects and will display the ToString() result of an item in the collection

    • Can wrap around the list to give a continuous scrolling effect using the Wrap property

  • HScrollBar

    • Unchanged

  • ImageList

    • Same as previous versions, but with an improved window for managing the images within the list. The MaskColor property is now TransparentColor.

  • Label

    • Essentially the same as previous versions

    • Caption is now Text

    • Can now display an image and text

    • The TextAlign property is especially useful. The text of a label beside a text box in VB6 would always be a few pixels higher than the text in the text box. Now, by setting the label’s TextAlign property so that the vertical alignment is Middle, this problem is solved.

    • Can now specify whether a mnemonic should be interpreted (if UseMnemonic is True, then the first ampersand (&) in the Text property specifies underlining the following character and having it react to the Alt key shortcut, placing the focus on the next control in the tab order that can hold focus, such as a text box).

  • LinkLabel

    • Identical to a label, but behaves like a hyperlink with extra properties such as LinkBehavior (for example, HoverUnderline), LinkColor, and ActiveLinkColor

  • ListBox

    • A list box can now hold a collection of objects, instead of an array of strings. Use the DisplayMember property to specify what property of the objects to display in the list, and the ValueMember property to specify what property of the objects to use as the values of the list items. (This is similar to the ItemData array from previous versions.) For example, a combo box could store a collection of employee objects, and display to the user the Name property of each, as well as retrieve the EmployeeId as the value of the item currently selected.

    • Can no longer be set to display check boxes using a Style property. Use the CheckedListBox control instead.

  • ListView

    • Same functionality as the VB6 version but with an improved Property Editor that enables you to define the list view item collection and its sub-items at design time

    • Sub-items can have their own font display properties.

    • New HeaderStyle property instead of HideColumnHeaders

  • MonthCalendar

    • Formerly known as MonthView

  • NotifyIcon

    • Gives a form an icon in the system tray

    • Tooltip of the icon is set by the Text property of the control

    • Pop-up menus are set using a ContextMenu control (see the “Menus” section earlier in chapter).

  • NumericUpDown

    • A single-line text box that displays a number and up/down buttons that increment/decrement the number when clicked

  • PictureBox

    • Image property defines the graphic to display instead of Picture

    • Use the SizeMode property to autostretch or center the picture.

  • ProgressBar

    • Now has a Step() method that automatically increments the value of the progress bar by the amount defined in the Step property

  • RadioButton

    • Formerly known as OptionButton

    • Use the Checked property to specify value (formerly Value).

    • Use CheckAlign and TextAlign to specify where the radio button and text appear in relation to the area of the control.

  • RichTextBox

    • Essentially the same control as before with a few new properties such as ZoomFactor, WordWrap, DetectURLs, and AutoWordSelection

    • Use the Lines() array to get or set specific individual lines of text of the control.

  • TabControl

    • Formerly known as the TabStrip control

    • Now has a TabPages collection of TabPage objects. A TabPage object is a subclass of the Panel control specialized for use in the TabControl.

    • Uses the Appearance property to display the tabs as buttons, if desired (formerly the Style property of the TabStrip control)

  • TextBox

    • Now has a CharacterCasing property that can automatically adjust the text entered into uppercase or lowercase

    • ReadOnly property now used to prevent the text from being edited. This used to be the Locked property. (The Locked property now determines whether the control can be moved or resized.)

    • Now has Cut, Copy, Paste, Undo, and ClearUndo methods

  • Timer

    • This is essentially unchanged from previous versions.

    • The timer is now disabled by default.

    • You cannot set the interval to zero to disable it.

  • TrackBar

    • Formerly known as the Slider control, it is essentially unchanged.

  • TreeView

    • Same functionality as in VB6 but with a new Node Tree Editor that allows you to visually design the tree

  • VScrollBar

    • Unchanged

Retired Controls

The following list outlines the controls from VB6 that you won’t find in Windows Forms and how to reproduce their functionality:

  • Spinner

    • Use the DomainUpDown or NumericUpDown control.

  • Line and Shape

    • Windows Forms has no Line or Shape control, nor any immediate equivalent. A “cheap” way of reproducing a horizontal or vertical line is to use a label control. Set its background color to that of the line you want, and then either the Size.Height or Size.Width value to 1.

    • Diagonal lines and shapes must be drawn using GDI+ graphics methods.

  • DirListBox, FileListBox, DriveListBox

    • You would typically use these controls to create a file system browser similar to Windows Explorer. Windows Forms has no equivalent controls. You can use the OpenFileDialog and SaveFileDialog (see the previous section) to meet your needs in most circumstances.

  • Image

    • Use the PictureBox control.

Working Without Control Arrays

Control arrays, a feature of VB6 and earlier versions, are not present in Windows Forms 2.0. They were needed for two capabilities:

  • To have a single method handle the events of multiple controls

  • To dynamically add new controls to your form at runtime

Both of these capabilities can be accomplished in Windows Forms, but the techniques used are different.

To have a single method handle multiple controls, you must arrange for those controls’ events to be attached to the method. You can do that with multiple controls specified in a Handles clause, or by using AddHandler for each control.

There is no Index property as in old-style control arrays in VB6. Instead, simply use the Sender parameter of the event handler to determine which control originated the event.

A simple example is helpful to see how to set this up. Create a new Windows application and set the Text property of the blank Form1 to Add Dynamic Control Demo. Then add two buttons to the form, as shown in Figure 15-26.

image from book
Figure 15-26

Double-click Button1 to switch over to the code that handles the Button1.Click event. To make this method respond to the Button2.Click event as well, simply add the Button2.Click event handler to the end of the Handles list, and then add some simple code to display a message box indicating what button triggered the event:

  ' Note the change in the method name from Button1_Click. Since ' two objects are hooked up, it's a good idea to avoid having the ' method specifically named to a single object. Private Sub Button_Click(ByVal sender As System.Object, _                  ByVal e As System.EventArgs) _          Handles Button1.Click, Button2.Click    Dim buttonClicked As Button    buttonClicked = CType(sender, Button)    ' Tell the world what button was clicked    MessageBox.Show("You clicked " & buttonClicked.Text) End Sub 

Run the program and click the two buttons. Each one will trigger the event and display a message box with the appropriate text from the button that was clicked.

Now enhance the program to add a third button dynamically at runtime. Add another button to your form that will trigger the addition of Button3, as shown in Figure 15-27.

image from book
Figure 15-27

Name the new button AddNewButton and add the following code to handle its Click event:

  Private Sub AddNewButton_Click(ByVal sender As System.Object, _                     ByVal e As System.EventArgs) _                     Handles addNewButton.Click     Dim newButton As Button     ' Create the new control     newButton = New Button()     ' Set it up on the form     newButton.Location = New System.Drawing.Point(184, 12)     newButton.Size = New System.Drawing.Size(75, 23)     newButton.Text = "Button3"     ' Add it to the form's controls collection     Me.Controls.Add(newButton)     ' Hook up the event handler.     AddHandler newButton.Click, AddressOf Me.Button_Click End  Sub 

When the AddNewButton button is clicked, the code creates a new button, sets its size and position, and then does two essential things. First, it adds the button to the form’s controls collection, and second, it connects the Click event of the button to the method that handles it.

With this done, run the program and click the addNewButton button. Button3 will appear. Then, simply click Button3 to prove that the click event is being handled. You should get the result shown in Figure 15-28.

image from book
Figure 15-28




Professional VB 2005 with. NET 3. 0
Professional VB 2005 with .NET 3.0 (Programmer to Programmer)
ISBN: 0470124709
EAN: 2147483647
Year: 2004
Pages: 267

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net