In the first part of the book, you learned some of the fundamentals of writing programs in Visual Basic. Along the way, you were exposed to some of the basics of working with controls. Part II of the book takes you deeper into the world of Visual Basic controls. In this first chapter, you will look at some of the standard controls, most of which have been a part of Visual Basic since version 1. You will see some of the basic operations of these controls, as well as see some of the new features that have been incorporated into Visual Basic 5.
Because several of the standard controls have been covered earlier in the book, they will not be covered in this chapter. These controls and the chapters that cover them are summarized in Table 9.1.
Control Name | Chapter |
TextBox | Chapter 14, "Working with Text, Fonts, and Colors" |
Label | Chapter 14, "Working with Text, Fonts, and Colors" |
Command Button | Chapter 4, "Working with Forms and Controls" |
PictureBox | "Doing Graphics," on the companion CD-ROM |
Image | "Doing Graphics," on the companion CD-ROM |
Shape | "Doing Graphics," on the companion CD-ROM |
Line | "Doing Graphics," on the companion CD-ROM |
Recall from these previous chapters that there are several properties, methods, and events that are common to almost all controls. Most controls have Name, Top, Left, Height, Width, Enabled, and Visible properties. There are also several other common properties that have yet to be discussed--until now.
The first of these properties is the TabIndex property. This property determines the order in which controls are accessed as the user presses the Tab key while the form on which the controls reside is active. The TabIndex property starts with zero for the first control you add to a form. As you add more controls, each control is given a TabIndex property that is one greater than the last control. If you design your form perfectly the first time, your controls will be accessed in the proper order and you will never have to worry about this property. However, changes to your form are inevitable and the order can get messed up. When this happens, you will have to reset the Tab order of the controls by setting the TabIndex properties.
Figure 9.1 shows a typical form used in a program. Since it is not possible to show the effects of good and bad tab orders in print, two programs are included on the companion CD to illustrate the concept. The form in Figure 9.1 is used in both programs. The two programs are BadTab.Vbp and GoodTab.Vbp. A user reasonably might expect to move from field to field in a logical order, which, in this case, would be First Name, Middle Initial, Last Name, Address, and so on. You should make sure the TabIndex property of your forms' controls causes the focus to flow correctly.
Since it is not possible to show the effects of good and bad tab orders in print, two programs are available on the CD-ROM to illustrate the concept. The form in Figure 9.1 is used in both programs. The two programs are BADTAB.VBP and GOODTAB.VBP.
FIG. 9.1
Users expect a form's focus to flow logically.
The only way to change the tab order of the controls on your form is to set the TabIndex property of each control that you need to shift. As you set a new value for the TabIndex property of a control, Visual Basic automatically adjusts the property values for all controls that have higher TabIndex property values than the new value.
NOTE: Even though Label controls can't receive the focus, they still have a TabIndex property. This is to aid in creating keyboard-friendly programs. TabIndex comes into play if a Label control's Caption property includes an access key; for example, a Label control whose Caption property is &Name will show the "N" to be an access key (Name). If the user presses the access key (in this case, Alt+N), the focus moves to the control with the next-higher TabIndex (assuming that it's a control that can receive the focus). If our Label control has a TabIndex property of 9, for example, you might have an associated TextBox control whose TabIndex property is 10. Then, when the user presses Alt+N, the focus moves to the "Name" TextBox, which is probably positioned next to the label. This technique, in effect, lets a Label control act as a caption for a text box.
Another property related to the TabIndex property is the TabStop property. TabStop is a property of any control that can receive the focus in a program. The value of the TabStop property determines whether the user can move the focus to the control by pressing the Tab key. The default value of True allows the user to use the Tab key. Setting the TabStop property to False means that the control won't receive the focus as the user presses Tab; however, it can still be accessed with the mouse.
Another useful property of many controls is the ToolTipText property, which enables you to display text in a ToolTip when the user pauses the mouse pointer over a control. ToolTips are used to help the user determine which controls will perform a desired action. A ToolTip is enabled if any text is entered for the ToolTip property. Figure 9.2 shows a ToolTip at work.
FIG. 9.2
ToolTips provide a clue to the function of a control.
Another common property of note is the Index property. If this property has a value (0 or greater), this indicates that the control is part of a control array.
Previously, you have seen how to acquire input from a user through the use of a text box. This works well for a number of data-gathering needs. But what if you just want a simple piece of information, such as "Do you own a car?" or "What is your marital status?" In these cases, the choice of answers you want to provide is limited to two or, at most, a few choices.
Although a text box works for getting this information, what is the user supposed to enter? For a "yes" or "no" choice, do you want the user to type out the entire word or just use the first letter? Or would you prefer true or false responses? By the same token, what should a person enter for marital status? Are you looking just for married or single, or do you want to include divorced and widowed?
These differences may not seem like much on the surface, but they can have a critical difference in how you write a program. If you set up a program to handle only the words yes and no, your program will have a problem if users type in "Maybe," or if they mistype a word.
You can eliminate this problem and provide the user with more direction to the responses you seek by giving them a specific set of choices from which to select. This can be accomplished through the use of check boxes and option buttons.
Check boxes and option buttons are great for small numbers of options, but sometimes you need the capability to handle a large number of options. For example, you might want to allow your users to pick the state in which they live instead of having to type it in a text box. Trying to cram 50 option buttons onto a form would be difficult and would make for a poorly designed form. Fortunately, there is another solution to the problem: lists.
Visual Basic provides two basic types of lists to handle large numbers of choices--list boxes and combo boxes. Lists can support a single choice or multiple choices. Some lists even allow the user to enter values that are not on the list.
Each of these controls used for obtaining user input will be discussed in the remainder of this chapter. We'll also look at scroll bars, which give the user an easy way to specify a value within a controlled range.
Visual Basic's CheckBox control is used to get an answer of either "yes" or "no" from the user. It works like a light switch. Either it is on or it is off; there is no in between. When a check box is on, a check mark (3) is displayed in the box. This indicates that the answer to the check box's corresponding question is "Yes." When the check box is off, or unchecked, the box is empty, indicating an answer of "No." Figure 9.3 shows a selected (on) and deselected (off) box.
NOTE: The check mark or empty box format is characteristic of the standard-form check box. If you set the check box's Style property to 1-Graphical, pictures are used to indicate checked and unchecked.
FIG. 9.3
A check box can indicate a "Yes" or "No" response to a
question.
The prompts used in a check box do not necessarily have to be in the form of a question. If you have looked at some of the option dialog boxes used for programs, you have seen check boxes used to specify which options should be turned on. The prompt for the check box is simply the option name, instead of a question. Figure 9.4 shows the Environment Options dialog box for Visual Basic, which shows this type of use.
FIG. 9.4
In the Environment tab of Visual Basic's Options dialog box, users can choose
the templates they want to be shown by selecting check boxes.
Although the check box has been around for a while, Visual Basic 5 has added a new twist to the old standard. When a check box's Style property is set to 1-Standard or 2-Graphical, your check box will appear in one of the following ways:
The appearance of each of these check box styles is shown in Figure 9.5.
FIG. 9.5
Graphical-style check boxes can give a new appearance to your programs.
To create a check box, select CheckBox control from the Toolbox and draw one (or more) on your form. When you first draw the check box, it has the default caption (prompt) of Check1. Since this will have absolutely no meaning to a user, you need to change the caption to something more descriptive. Select the Caption property from the Properties window and change it to something meaningful. At this point, what you do to control the appearance of the check box depends on the style of check box you select.
Controlling the Appearance of a Standard Check Box If you are creating a standard check box, leave the Style property in its default setting of 0-Standard. After you have selected the standard style, there are several things you can do to change the appearance of the check box:
The effects of the Appearance and Alignment properties are shown in Figure 9.6. The default value of the Appearance property is 3-D and the default value of the Alignment property is left-justified. Both the Alignment and the Appearance properties are read-only at runtime; this means that they can only be set while you are in the design environment. You cannot change these properties with program code.
FIG. 9.6
By modifying properties of your check boxes, you can produce a wide variety
of visual effects.
CAUTION: If you use right justification for the check box, make sure that the control is sized so that the box is next to the prompt. Otherwise, a misalignment (like the one in Figure 9.6) can cause confusion for the user.
Controlling the Appearance of a Graphical Check Box If you are creating a graphical check box, set the Style property to 1-Graphical. Several of the properties that you can set for the Standard check box also can influence the appearance of the graphical check box. Specifically, you can set the font used for the prompt, and you can set the colors of the check box. Also, the Appearance property can be used to give the control a flat or 3-D appearance. The Alignment property has no effect on the graphical check box. However, these properties are not the really great feature of the graphical check box--the greatest feature is that you can include pictures on the check box. In fact, you can assign three different pictures to the check box, one for each of the three different states. The properties used to set the pictures, and the check box states they represent, are summarized in Table 9.2.
Property | State | Description |
DisabledPicture | Disabled | The Enabled property of the check box has been set to False. This indicates that the user cannot access this check box. |
DownPicture | Checked | This indicates that the user has selected the option represented by the check box. |
Picture | Unchecked | The user has ot selected this check box. |
To set any one of these picture properties, you can enter the file name (including path) of a bitmap or other graphics file. You also can use the Load Picture dialog box to select a picture to be loaded. This is the easier of the two methods for selecting a picture. Figure 9.7 shows the various states of a graphical check box.
FIG. 9.7
Pictures can represent the different states of the check box.
Setting the Initial Value o matter which style of check box you choose to create, one final thing that you need to do is set the initial state for the control, either checked or unchecked. Whether the check box is checked or not is controlled by the Value property. If you want the check box to be checked when the program starts, set the Value property to 1-Checked; otherwise leave the property with a setting of 0-Unchecked, which is the default value.
NOTE: There is a third setting possible for the check box's Value property. The setting is 2-Grayed. When set to this value, the check box will show a gray check mark in the box. This usually indicates that the choice represented by the check box must be True, and, thus, the user cannot change it. The user cannot set the check box to this value.
When a check box is shown on a form, the user can change the value of the check box by clicking it (unless it's gray). The user also can use the Tab key to move the focus to the check box and then press the spacebar to change its value. One click of the mouse or one press of the spacebar toggles (changes) the value from checked to unchecked, or vice versa. A second click returns the check box to its original setting.
For most programs, you will want to determine in your code whether the check box is checked. You do this by looking at the Value property. The code in Listing 9.1 shows how you would set the global options in a program using an Options dialog box comprised of check boxes. Note the use of the intrinsic constant vbChecked, which represents a Value property setting of 1. The intrinsic constants vbUnchecked and vbGrayed also are available to represent the other possible values. The form used for this dialog box is shown in Figure 9.8.
glbSecurity = False glbAddUser = False glbPassChange = False If chkSecurity.Value = vbChecked Then glbSecurity = True If chkAddUser.Value = vbChecked Then glbAddUser = True If chkPassChange.Value = vbChecked Then glbPassChange = True `************************ ` Alternate coding `************************ If chkSecurity = vbChecked Then glbSecurity = True If chkAddUser = vbChecked Then glbAddUser = True If chkPassChange = vbChecked Then glbPassChange = True
NOTE: While specifying the Value property makes reading the code easier, Value is the default property of the check box. Therefore, the code could be written the way it is shown in the last three lines of Listing 9.1.
FIG. 9.8
A user may select any number of check boxes, such as those contained in a
typical Options dialog box.
NOTE: You can provide an access key for check boxes by specifying an ampersand (&) in the Caption property immediately before the desired access key character. For example, if a check box's Caption property is &Registered Voter, the user can check or uncheck it by pressing Alt+R, rather than clicking the mouse. The same concept applies to option buttons, which are discussed in the following section.
Another way to allow users to make choices is through the use of option buttons. Option buttons let the user select a single item out of a group of items. This is the equivalent of a multiple-choice test. You can choose one, and only one, option button from a group. A typical option button group is shown in Figure 9.9.
FIG. 9.9
Option buttons provide a "pick one" capability for your programs.
Option buttons work like the speed selection buttons on a blender. If you press down one button, all the other buttons come up. The option buttons work the same way insofar as that, when you select one button, whichever other button was currently selected becomes deselected.
To use option buttons, you need to create a button for each possible choice the user can select. For instance, you might have the user select eye color from the choices blue, hazel, green, or brown. For this, you would need four option buttons.
Placing the Buttons on the Form To create the set of option buttons, you draw each button on the form and set its properties. Like the check box, the prompt for the option button is contained in the Caption property. To create the form shown in Figure 9.9, draw four buttons on the form and set the Caption of each button to one of the four eye color choices--blue, hazel, green, and brown. For other programs, you might have more or fewer options than four. You can create as many option buttons as are needed to allow for all the choices you want to present to your user.
TIP: If you need to include the possibility of an option other than the ones you have presented, you can use an option button labeled "Other" and have a text box next to it to accept the user's entry. The text box would be enabled only when the user selected the "Other" button.
Setting the Appearance of the Buttons Option buttons have the same capabilities for controlling the appearance of an individual button as a check box. You can, of course, choose different fonts for the prompts, and different colors, too. As with the check box, you also can change the Alignment property of the option buttons to place the circle to the right or left of the prompt; however, if you use right-justification, make sure that the control isn't so large that the caption is too far from the button. The arrangement of individual buttons within the group is an additional factor in the appearance of option buttons. You can arrange buttons either horizontally or vertically, as shown in Figure 9.10. My personal preference is to use vertical groups when using standard-style buttons so that all the circles in the buttons are aligned. If you are using Graphical-style buttons, the arrangement is less important.
FIG. 9.10
Option buttons may be arranged in either horizontal or vertical groups, depending
on your preference.
Like the check box, option buttons in Visual Basic 5 can be created in either of two styles--standard or graphical. To choose the type of button, you set the Style property of the button. For the graphical-style button, you then set the pictures that will be displayed for each of the button states. The different styles of option buttons are shown in Figure 9.11.
FIG. 9.11
Your choice of standard or graphical option buttons can profoundly affect
your program's appearance.
NOTE: Although it isn't required that you use the same style for all the option buttons on your form, it is a good idea to use a consistent style to avoid confusing the user. This will also help prevent forms that look too cluttered with unnecessary graphics.
Choosing the Initial Button Once you have placed all the required buttons on the form, you probably will want to designate one of the buttons as the initial choice. To do this, select the button you want to be the initial choice and set its Value property to True. The circle associated with this button becomes a filled circle (or the graphical button displays the picture in the DownPicture property). All the other buttons on the form change to empty circles, or display the picture in the Picture property. (Remember, only one button can be selected at a time.)
When the option buttons are displayed in your program, the user can choose one by clicking it. A button also may be selected by using the cursor keys. Whichever option button has the focus is the one that has the filled circle. The filled circle indicates the choice on-screen.
Since your program can't see the screen to tell which option button is selected, it needs another means to ascertain which button the user picked. The Value property of each option button tells your program whether that particular button is selected. The property is set to True for the selected option button and False for all others. Therefore, you need to examine the Value property of each option button to find the one that is True.
Looking at the eye color example, the code in Listing 9.2 examines the Value property of the option buttons and prints out the appropriate eye color on the form. To be able to run this code, we added a command button (which we named cmdColorChoice) to the form. The code is contained in the Click event procedure for the command button.
Private Sub cmdColorChoice_Click() Form1.Cls If BlueEyes.Value Then Form1.Print "Your eyes are blue" ElseIf GreenEyes.Value Then Form1.Print "Your eyes are green" ElseIf HazelEyes.Value Then Form1.Print "Your eyes are hazel" ElseIf BrownEyes.Value Then Form1.Print "Your eyes are brown" End If End Sub
Although only one option button placed directly on a form can be selected at a time, there is a way to give your users choices from several groups of buttons at the same time. Grouping your buttons allows users to select items cafeteria-style, like one entree, one vegetable, one dessert, and one drink. When the buttons are grouped properly, the user can select one, but only one, button from each group of buttons. The cafeteria example is shown in Figure 9.12.
FIG. 9.12
You can create multiple option-button groups that enable the user to select
one button from each group.
The secret to creating button groups is the use of a container control, which is a control that can hold other controls within its borders. There are several controls that can be used for this purpose, including the Frame control, the Picture control, the SSTab control, and the Shape control (refer to Figure 9.10). Each of these controls can hold other controls within its borders. Any controls placed within a container control are treated as a part of the container. This means that when a container is moved, all the controls within it move, too. Likewise, if a container is disabled, none of the controls in it are accessible.
The purpose of using a container with option buttons is to segregate the buttons within the container from buttons that are on the form or in another container. This means that the user can select one button from each container, in addition to one button that is on the form itself. You can create as many containers as you need. Refer to Chapter 13, "Using Containers," for more detailed information about working with containers.
See "Creating Groups of Option Buttons," Chapter 13
Because your users now can select a button from each group, you need a set of statements, such as the ones in Listing 9.2, for each group of buttons.
NOTE: While check boxes and option buttons may appear to be very similar, the fact that only one option button (within a group) may be selected makes them quite different functionally. For example, if you offer the user a group of check boxes, you can obtain multiple on/off responses at once that you couldn't get with option buttons. This is handy when a question you ask the user might have more than one valid response (the responses aren't mutually exclusive). Also, if you have a group of option buttons, the user can't deselect all options if one option has been selected. The user can select and deselect check boxes at will. This is an important consideration if you want your user to be able to select none of your choices.
Often, you may want to give your user a greater number of choices than might be feasible with check boxes and option buttons. Visual Basic supplies two controls that allow you to present your user with a list of choices. Each of these controls has the capability of presenting your user with a list that can get rather lengthy if necessary.
The most straightforward control of this type is the ListBox control. We'll discuss the other one, the ComboBox control, a little later in the section "Using Combo Boxes to Handle Choices."
The simplest control that can be used to present a list of choices is the ListBox control. Figure 9.13 shows a simple list used to pick a state abbreviation for use on a mailing label. This simple list shows all the components that make up the list box.
FIG. 9.13
A simple list box contains a series of choices for the user.
The key parts of the list box are the following:
To the user, the simple list box is similar to choosing channels on their TV. The cable company decides which channels to put on the selection list. The customer then can pick any of these channels, but can't add one to the list if they don't like any of the choices provided. With the list box, the choices are set up by you, the programmer; the user can select only from the items you decide should be available.
Setting Up the List Box When you first draw a list box on the form, it shows only the border of the box and the text List1 (for the first list box). There is no scroll bar present and, of course, there are no list items. A vertical scroll bar is added to the list box when you have listed more items than fit in the box. This is done automatically by the control. After you draw the list box, the next step in setting it up is to add items to the list. These will be the choices available to the user. The list items are stored in a string array in the List property of the list box. Each list item is an element in this array. To add items to the list at design time, select the List property from the Properties dialog box. You will see the text (List) and a down arrow in the property field. Click the down arrow to access the list item input area, as shown in Figure 9.14.
FIG. 9.14
You add items to a list box by using the item input area of the List property.
You add items to the list by typing in the text that you want to appear in the list box. Each line in the List property corresponds to a selection that is presented to the user. After you add an item to the list, press Ctrl+Enter to move to the next line of the list.
After you have added all the items you need, press Enter to accept the list. At this point, the list box displays all the items you have entered and, if necessary, includes a vertical scroll bar at the right of the list. Note that the list box doesn't have a horizontal scroll bar if the choices are too wide for the control, so you should make sure that the list box is wide enough to display all of its entries. It's also a good idea to keep the items' textual names as short as possible to help avoid this problem.
Modifying the Item List from Your Program There may be situations at runtime where you want to modify the list of items displayed in the list. For example, if you are using a list box to display food items, you might want to set up the list so that meat items are not displayed for a vegetarian user. To accommodate these types of situations, the list box allows you to use code to add items to or remove items from the list box as the program is running. If you want, you even can place code in the Load event procedure of your form to set up the initial list, instead of typing the entries in through the Properties window. To manipulate items in the list, use the AddItem and RemoveItem methods.
Using the AddItem method is very straightforward. You simply specify the name of the ListBox control, the name of the method, and specify a string that you want added to the list. This is shown in the following line of code:
lstAvailable.AddItem "Corvette"
The list item can be a string of text or a number (though numbers are not typically handled by lists), and can be in the form of a literal value or a variable. Remember, if you are using a literal string, you need to enclose it within double quotes. There is an optional parameter, Index, that may be used with the AddItem method. This parameter specifies the location within the list where you want the new item to appear. You will specify the index value of the item in front of which you want to add your item. For example, if there are five items in the list and you want your item to appear ahead of the third item, you use code like the following:
lstAvailable.AddItem "Corvette", 2
NOTE: The Index of the list items is zero-based. This means that the first item on the list has an index of 0, the second item has an index of 1, and so on.
If you include an index value, it must be separated from the list item by a comma. Including the index causes the item to be placed exactly where you want it. If you omit the index, the item is placed at the end of the list, or in alphabetic order if the Sorted property is set to True.
CAUTION: If you specify an index value that is outside the range of indexes in the list box, an error will be generated. You can avoid this by checking the ListCount property, which reports the number of items currently in the list, to make sure this doesn't occur. Also, specifying an index less than 0 will cause an error.
Deleting an item from the list is a little trickier than adding an item because you need to know the index of the item to be deleted. If you know in advance what the index is, you can simply delete the item by using the RemoveItem method. For example, the following code deletes the first item in the list:
lstAvailable.RemoveItem 0
In a more typical situation, you will want to delete an item that the user has selected. You will learn about determining the user's selection in the section "Determining the User's Choice" a little later in the chapter. For now, you can look at the code in Listing 9.3 to see how to delete the selected item.
Dim LstIdx As Integer LstIdx = lstAvailable.ListIndex If LstIdx >= 0 Then lstAvailable.RemoveItem LstIdx
In another situation, you might want to remove a specific item based on the item's text. This involves searching the list to find the item and then using the RemoveItem method to delete the item (see Listing 9.4).
Dim I, LstIdx As Integer LstIdx = -1 For I = 0 To lstAvailable.ListCount - 1 If lstAvailable.List(I) = "Mustang" Then LstIdx = I Exit For End If Next I If LstIdx >= 0 Then lstAvailable.RemoveItem LstIdx
TIP: If you want to remove all the items in a list, use the Clear method (for example, lstAvailable.Clear). Essentially, this method throws away your entire list.
Sorting the List In the preceding section, you saw how to modify the list by adding and removing items. You also saw that you can add an item to a specific location by specifying an index. But what do you do if you want your entire list sorted in alphabetic order? Fortunately, this is a very simple task. To sort the list, you simply set the Sorted property to True. Then, no matter in which order you enter your items, they appear to the user in alphabetic order. The indexes of the list items are adjusted as they are added so that they remain in proper order.
Setting the Appearance of the List In previous versions of Visual Basic, lists like the one shown in Figure 9.13 were the only available styles--In Visual Basic 5, you now have a choice. You can use a standard list, or you can make your list look like a series of check boxes. You handle the selection of the list type by setting the Style property. The two settings of the property are 0-Standard and 1-Checkbox (see Figure 9.15). This property also can be changed at run time by setting its value to one of the intrinsic constants vbListBoxStandard or vbListBoxCheckBox, respectively.
FIG. 9.15
Checkbox-style list boxes provide the user with an intuitive way to select
multiple items.
Another way to change the list's appearance is to use the Columns property. The default value of the property is 0. This results in the standard list box previously discussed. Setting the property to 1 causes the list to be presented one column at a time, but to scroll horizontally instead of vertically. Setting the property to greater than 1 causes the list to display in the number of columns specified by the property (for example, a value of 2 displays the list in two columns). When the list is displayed in multiple columns, the list scrolls horizontally. The Columns property can be used with either the Standard or Checkbox styles of lists. These styles are shown in Figure 9.16.
FIG. 9.16
You also can create multicolumn lists.
The list works the same way no matter how many columns you use.
For most programs, you will want to retrieve the user's selection and do something with it. To find out what the user selected, you need to work with two properties of the list box: the ListIndex and List properties.
The ListIndex property reports the index number of the item that was selected. You then can retrieve the actual item from the List property by using the index number. The following code displays the selected item in a text box:
idx = Fruits.ListIndex ChosenFruit.Text = Fruits.List(idx)
Handling Multiple Choices There are occasions when you need to let the user select more than one item from a list. The list box supports this with the MultiSelect property. This property has three possible settings: 0-None, 1-Simple, and 2-Extended. A setting of 0-None means that multiple selections are not permitted, and the list box can accept only one selection at a time. This is the default setting. The other two settings both permit multiple selections; the difference is in how they let the user make selections. This will be explained through the example that follows.
One great use of multiple item selections is in an order-entry system. When a person places an order with a company, they usually are buying more than one item. A multiple-selection list allows the salesperson to select all the items for the order and then to process the entire order at once.
With a setting of 1-Simple, users can click an item with the mouse to select it, or click a selected item to deselect it. If they is use the keyboard to make the selection, they can use the cursor keys to move the focus (the dotted line border) to an item, then press the spacebar to select or deselect it. Figure 9.17 shows a list with multiple items selected.
FIG. 9.17
You can select multiple items from a list with the proper setting of the MultiSelect
property.
The other setting of the MultiSelect property, 2-Extended, is more complex. In this mode, users quickly can select a range of items by clicking the first item in the range and then, while holding down the Shift key, click the last item in the range--all items in between the first and last item are selected. To add or delete a single item to or from this selection, the user holds down the Ctrl key while clicking the item.
Getting All the Selections Getting the selections from a multiple-selection list box is a little different than getting them for a single selection. Since the ListIndex works only for a single selection, you can't use it. Instead, you have to examine each item in the list to determine whether it is selected. Whether an item is selected or not is indicated by the list box's Selected property. This property is an array that has an element for each item in the list. The value of the Selected property for each item is either True (the item is selected) or False (the item is not selected).
You also need to know how many items are in the list so that you can set up the loop to check all the selections. This information is contained in the ListCount property. The following code prints onto the form the name of each list item that is selected:
numitm = Fruits.ListCount For I = 0 to numitm - 1 If Fruits.Selected(I) Then Form1.Print Fruits.List(I) Next I
What if you want the user to see a meaningful list, such as a list of names, but you also want to have the list remember a number that's associated with each name? The ItemData property of a list box is, in essence, an array of long integers, one for each item that has been added to the list box. No matter what position an item occupies in the list box, the ItemData array remembers the number associated with that particular element. This happens even if the list box's Sorted property is True, meaning that items won't necessarily be listed in the order that they're added. For example, the ItemData array element associated with the first item in a list box named List1 can be accessed as List1.ItemData(0). The array element for the currently selected list box entry can be accessed with List1.ItemData(List1.ListIndex) (recall that the ListIndex property reports which item is currently selected).
As items are added to a list box, an associated element is created in the ItemData array. Of course, it's your job to place the appropriate value into the proper position of the ItemData array. So how can your program know into which list box position a newly added item went, especially if the list box is sorted? Visual Basic makes this easy. A list box's NewIndex property contains the index number of the most recently added item in the list. The following code adds a new customer to a sorted list box and then adds that customer's account number to the correct element of the associated ItemData array:
lstCustomers.AddItem "Thomas, June" lstCustomers.ItemData(lstCustomers.NewIndex) = "21472301"
Now, our program can allow the user to select from a list box containing meaningful elements (names), but the background processing can be done with an associated number, which is easier for the computer. This is illustrated in the Click event procedure of the list box:
Private Sub lstCustomers_Click() Dim lgThisCust As Long lgThisCust = lstCustomers.ItemData(lstCustomers.ListIndex) Call LookUpAccount(lgThisCust) End Sub
One of the best ways to demonstrate the use of the methods for modifying a list is to create what is known as a two-column pick list. You probably have seen these pick lists used in a number of applications. A form contains two lists; one list contains the available choices and the other list contains the user's selections. As the user selects an item from the available list, the item is removed from that list and is added to the selected list. If the user removes a selection, the process is reversed. These lists also give the user the capability to select all items, or remove all items. Figure 9.18 shows the list created by the following example.
FIG. 9.18
Two-column pick lists clearly show the user's choices.
To start creating the list, follow these steps:
Private Sub cmdSelect_Click(Index As Integer) Dim I, LstIdx As Integer, MovItm As String Select Case Index Case 0 `Single selection LstIdx = lstAvailable.ListIndex If LstIdx < 0 Then Exit Sub MovItm = lstAvailable.List(LstIdx) lstSelected.AddItem MovItm lstAvailable.RemoveItem LstIdx Case 1 `Select all If lstAvailable.ListCount = 0 Then Exit Sub For I = 0 To lstAvailable.ListCount - 1 MovItm = lstAvailable.List(I) lstSelected.AddItem MovItm ext I lstAvailable.Clear Case 2 `Single removal LstIdx = lstSelected.ListIndex If LstIdx < 0 Then Exit Sub MovItm = lstSelected.List(LstIdx) lstAvailable.AddItem MovItm lstSelected.RemoveItem LstIdx Case 3 `Remove all If lstSelected.ListCount = 0 Then Exit Sub For I = 0 To lstSelected.ListCount - 1 MovItm = lstSelected.List(I) lstAvailable.AddItem MovItm ext I lstSelected.Clear End Select End Sub
As shown in Listing 9.5, the code works only when the user clicks the command button. You would probably also want your users to be able to select items directly from the list. You can do this by placing code to call the command button procedure in the DblClick event procedure of each list (see Listing 9.6).
Private Sub lstAvailable_DblClick() cmdSelect_Click 0 End Sub Private Sub lstSelected_DblClick() cmdSelect_Click 2 End Sub
As an exercise, you can modify this pick list to handle multiple selections by the user in each list.
Another control that enables you to present lists to the user is the ComboBox control. The combo box can be used in three different forms.
The combo box has many things in common with the list box. Both use the AddItem, RemoveItem, and Clear methods to modify the contents of the list. Both can present a sorted or an unsorted list. Both support the ItemData array and NewIndex property, mentioned earlier. However, there are some things that one box can do but the other cannot.
The main thing the combo box lacks is support for multiple selections. The key advantage of the combo box, though, is that it allows the user to enter a choice that is not on the list. This works like an election ballot, where you can choose a candidate from the list of those running, or write in your own.
NOTE: The drop-down list does not support the user entering choices that are not on the list.
FIG. 9.19
Each of the three styles of combo boxes behaves differently when the user
selects his choice.
This section explains how to use the different forms of the combo box. The drop-down list is examined first because it is the simplest of the combo box styles.
A drop-down list functions exactly like a list box. The key difference is that the drop-down list takes up less room on your form. When users want to select an item from the list, they click the down arrow, located to the right of the box, to extend the list. After the drop-down list appears, they then make a selection by clicking the item they want to choose. After the selection is made, the list retracts like a window shade, and the selection appears in the box.
You create a drop-down list by drawing a combo box on the form, and then setting the Style property to 2-Dropdown List. You then can begin adding items to the list by using the List property, just like you did for the list box. However, keep in mind that the user can't add an item that's not in the list.
The drop-down list is very useful for presenting a number of choices in a small amount of space. However, the real power of the combo box is its capability to allow users to enter choices other than those on the list. This capability is available with the other two styles of combo box--the simple combo box and the drop-down combo box. Both styles provide a list of items from which you can select and both allow you to enter other values. The difference between the two styles is the way in which you access items already in the list.
A simple combo box is set up by drawing the control on the form, and then setting the Style property to 1-Simple Combo. With the simple combo box, the user can access the items in the list using the mouse or the arrow keys. If the user doesn't find what he wants on the list, he can type in a new choice.
The drop-down combo box works like a combination of the drop-down list and the simple combo box. You select an item from the list the same way you would for a drop-down list, but you also can enter a value that is not on the list. The drop-down combo box is created by setting the Style property to 0-Dropdown Combo. The drop-down combo box is the default setting of the Style property.
As with the list box and the drop-down list, you can use the List property to add items to the list of selections. You also can modify the list for any of the combo box styles while your program is running. As with the list box control, you modify the list by using the AddItem, RemoveItem, and Clear methods.
Depending on your application, you might want to set the initial item for a combo box. An example of setting the choice is in a program that needs to know your citizenship. You can provide a list of choices, but set the initial value to "U.S. citizen" because that would be the selection of most people in this country.
You set the initial value by using the ListIndex property, as shown in the following code:
Fruits.ListIndex = 3
This statement causes the fourth item in the list to be displayed when the combo box is first shown. (Remember, the list indexes start at 0.) Setting the initial choice will work with any of the three combo box styles. You also can set the initial choice of the combo box by setting the Text property to the desired value. If you do not set an initial choice by setting the index, the text contained in the Text property will be displayed.
CAUTION: The initial value of the Text property is the name of the combo box. If you do not want this to appear in your combo box on start up, set either the ListIndex property or the Text property in code.
TIP: If you want your combo box to be blank when the form is first shown, simply delete the contents of the Text property while you are in the design environment.
Getting the user's choice from a combo box is different than getting it from a list box. With a combo box, you need the capability to handle users entering a value that is not on the list. You can retrieve the user's choice with the Text property of the combo box. The Text property holds any value that is typed in by the user, or holds the item selected from the list. The following line of code prints the user's selection:
Form1.Print cboFruits.Text
If you include a combo box as part of a data entry form, you may want the capability to take any new items entered by the user and add them to the list of choices. That way, when the user enters another record, they won't have to type the same choice again.
The combo box does not have a specific method to handle this function, nor does the addition of a new item trigger a particular event. However, you can take advantage of the fact that there will be more than one control on the form into which the user must enter data. A typical data entry form for a personnel application is shown in Figure 9.20. The combo box to which you want to add choices is the one for College Attended. As users enter colleges not on the list, those colleges are added to the list so that they only have to be entered one time.
FIG. 9.20
This typical application uses a combo box to obtain college information.
Handling this enhancement makes one assumption--in almost all cases, after users enter the college name, they will move to the next field to enter more information, or click a command button to execute a task. Either way, the focus moves from the combo box to another control. This triggers the LostFocus event. Therefore, you can use this event as the trigger to add new items to the list. When the user moves the focus, your code first needs to retrieve the value of the Text property as the new item. Next, you need to scan the list of items to make sure that the item does not exist already. Then, if the item is, in fact, new, you can add the item to the list. Listing 9.7 illustrates how this can be accomplished.
Dim NewItm As String, I As Integer, AddNewItm As Boolean AddNewItm = True With cboCountry ewItm = cboCountry.Text For I = 0 To .ListCount - 1 If .List(I) = NewItm Then AddNewItm = False Exit For End If ext I If AddNewItm Then .AddItem NewItm End If End With
You have seen scroll bars used in a text box for multiple line editing and in lists to access long lists of items. While they look basically the same, these scroll bars are different from the scroll bar controls in Visual Basic.
Scroll bars work like the volume control on your stereo system. Your stereo has minimum and maximum volume settings. The volume knob, or slider bar, enables you to set any volume in between the minimum and maximum ranges. Scroll bars also have minimum and maximum settings and let you use a slider to set a value anywhere within the range.
Visual Basic provides two types of scroll bars for entering numerical data: the vertical scroll bar and the horizontal scroll bar. These two controls are shown in Figure 9.21. The two scroll bars are referred to in the documentation as the VScrollBar and HscrollBar controls, respectively.
FIG. 9.21
The VScrollBar and HScrollBar controls can be used to enter or display numerical
data.
The only difference between these two controls is the orientation of the bar on the form. All the methods, events, and properties of the controls are the same. The following discussion examines the HScrollBar control, but it applies equally to the VScrollBar.
The scroll bar is capable of accepting whole numbers (integers) anywhere in the range of -32,768 to 32,767. One typical range is from 0 to 100, where the user enters a number as a percentage. Another possible use of scroll bars is to control the speaker volumes in a multimedia application. Also, if you have experimented with the colors in Windows, you have seen the scroll bars that enable you to enter the relative amounts of red, green, and blue that will appear in a color. These bars have a range of 0 to 255, the possible values of the color settings.
Setting the Upper and Lower Boundaries The range of values that can be entered with the scroll bars is determined by the settings of the Min and Max properties. The Min property sets the lower boundary of the value range and has a default setting of 0. The Max property sets the upper boundary of the range and has a default value of 32,767. You can change the settings of these properties from the Properties window, or through the use of code statements, as shown in the following example. For this example, use the Properties window to set the Min property to 0 and the Max property to 100.
hsbPercent.Min = 0 hsbPercent.Max = 100
Controlling the Size of the Value Changes If you have used a scroll bar in a word processor or other program, you know that clicking the arrow at either end of the bar moves you only a short distance, but clicking in between an arrow and the position button moves you a greater distance. The scroll bar controls work the same way, and you get to set how much the numbers will change with each kind of move. The number entered in a scroll bar is contained in the Value property. This property changes every time the user clicks the scroll bar or drags the position button, as indicated in Figure 9.22.
FIG. 9.22
Clicking various parts of the scroll bar changes its value by different amounts.
The amount that the Value property increases or decreases when an arrow is clicked is controlled by the SmallChange property, which gives you very fine control over the numbers being entered. Its default value is 1, which probably is a good number to use for most purposes.
When you click between the arrow and the position button, the Value property can change by a different amount than if you click an arrow. The amount of this change is set by the LargeChange property. The default setting of the LargeChange property is 1. The setting you use depends on your application. For example, a value of 10 is a good number if you are setting percentages.
TIP: A good rule of thumb is to set the LargeChange property to a number about 5 to 10 percent of the total range (for example, a value of 50 for a 0 to 1000 range).
A scroll bar, by itself, is not all that useful. The user cannot determine the range of numbers. Without knowing the number range, making a guess at the actual value of the scroll bar is fruitless. There are several ways to display additional information about the scroll bar value that will make them easier for the user to work with. These options are discussed next.
First, you can tell the user the minimum and maximum values. You can do this by adding label controls above (or beside) each end of the scroll bar. Although these labels help users to see what is the approximate value, they still cannot see the exact value. The only way to know the actual value of the scroll bar is to display it in another control, such as a text box or label. Figure 9.23 shows these enhancements.
FIG. 9.23
Associating labels or text boxes with the scroll bar shows users the range
and actual value.
Assigning the value of the scroll bar to a text box is easy. You use a code statement like the following:
txtActValue.Text = hsbPercent.Value
The statement itself is the easy part. What's tricky is knowing where to put the statement. To show the value at all times, you actually have to place this statement in three events:
If you use a text box to display the actual value of the scroll bar, you can let the user enter a value directly in the text box. Then, using the Change event of the text box, you can update the value of the scroll bar accordingly. The code for this process is shown in Listing 9.8.
Dim ValSet As Integer ValSet = Val(txtValue.Text) If ValSet > hsbPercentage.Max Then ValSet = hsbPercentage.Max If ValSet < hsbPercentage.Min Then ValSet = hsbPercentage.Min hsbPercentage.Value = ValSet
Another control that comes in handy on occasion is the Timer control. This control works like the cooking timer on your microwave oven. It counts down a specified amount of time and then fires the Timer event. You can specify the action that should occur by writing code for the Timer control's Timer event procedure.
The timer works by counting the number of milliseconds (thousandths of a second) that have elapsed since the form containing the control was loaded, or since the Timer event was last fired. When the count reaches the amount set by the Interval property, the control triggers the Timer event and runs whatever code is present.
You set up a Timer control by first drawing it on the form. At design time, the Timer control shows up as an icon on the form, no matter how large you draw it to begin with (see Figure 9.24). The Timer control is not visible on the form when your program is running.
FIG. 9.24
The Timer control is visible only at design time.
To make the control work, the Interval property is the only property that you need to set. You can set the Interval property for any value between 0 and 65,535. A setting of 0 disables the Timer control. Any other setting specifies the number of milliseconds that should elapse before the Timer event is triggered. The minimum setting, 1, is shorter than the blink of an eye. The maximum setting is just a little longer than a minute. If you want 10 seconds to elapse, set the Interval property to a value of 10,000.
Since the maximum value of the Interval property corresponds to about a minute, how can you set up longer time intervals? You set up code within the Timer event that tracks how many times the Interval has elapsed, as shown in Listing 9.9.
Private Sub tmr_Timer() Static ElTime If ElTime >= 20 Then MsgBox "Time's Up!" ElTime = 0 Else ElTime = ElTime + 1 End If End Sub
The first line of the code defines the variable that tracks the number of times the interval has elapsed. The keyword Static means that the value of the variable is maintained even after the event procedure is ended, so it will be intact the next time the event procedure is executed. (For more information about Static variables, see Chapter 8, "Programming Visual Basic.")
See "Determining Where a Variable Can Be Used," Chapter 8
The conditional statement determines whether the timer has elapsed 20 or more times. If so, a message box displays, informing the user. The number of times then is reset to 0 to start the cycle over again. If the number of times is less than 20, one is added to the ElTime variable and the procedure is exited.
By adjusting the Interval property of the timer and the number of times it elapses, you can make the Timer control count any amount of time.
A useful function for the Timer control is to blank the screen after a specified period of time. Screen-blanking routines were originally used to prevent damage to the screen from having the same image displayed for long periods of time. The more current usage is for security reasons. Many times, people are in the middle of an application and have to leave their desk for a few minutes to attend to other tasks. If the users are not careful, sensitive information can be left on-screen for anyone to see. Screen blankers provide a way to hide this information if there is no program activity for a specified period of time. Of course, this security measure would reasonably need to be enhanced with some type of password protection before the original screen is restored.
The Timer control can be used to create a simple screen blanker for use with your programs. To start, add a Timer control to your main form. Set the Interval property of the timer to the desired amount of time. (For demonstration purposes, set the timer to 10 seconds, or an Interval value of 10,000.)
Next, add a second form to your program. You now need to change the BackColor property of the new form to black and change the BorderStyle property to 0-None. This will give you a black form with no borders, captions, or buttons when the program is run. You then need to add the following line of code to the form's Load event:
frmScreenBlank.WindowState = vbMaximized
This code causes the form to be maximized as it is loaded, covering the entire screen.
Now all you need is code to activate the blank form and to deactivate it. The code to activate the form is placed in the Timer event of the Timer control on the first form. The code is as follows:
frmScreenBlank.Show
This causes the form to be loaded and displayed when the Timer event is triggered. Finally, to deactivate the blank form, place the following line in both the Click and KeyPress events of frmScreenBlank:
frmScreenBlank.Hide
This code causes the blank form to be hidden when a key is pressed or the mouse is clicked while the blank form is displayed. When the form is hidden, the original form and the rest of the screen once again displays. Now, run the code and try it for yourself.
To add to the security of the screen blanker, you can add a password routine to the code that hides the form. This way, the user has to enter a password before the screen displays again. You also might want to have the application terminate after a set period of time instead of just having the screen go blank.
This chapter discussed the use of a number of standard controls that are included with Visual Basic. You have seen examples of how to use each one. You can enhance your understanding of these controls by practicing! Try using them in a variety of applications to see how they behave in different situations. For more information about using these controls and others with which they may interact, refer to the following chapters:
© Copyright, Macmillan Computer Publishing. All rights reserved.