![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Advanced Visual Basic Techniques
Creating Controls DynamicallyUsing a ScrollArea control within a Viewport control, a program can implement scrolling regions in Visual Basic. Some applications can add all the required controls to the ScrollArea at design time. The ExpenseReporter application, however, does not know how many rows of expense fields it will need until run time. ExpenseReporter adds a new expense row to the end of the ScrollArea whenever the user enters data in the row that is currently last. This step always gives the user a fresh row for entering data. ExpenseReporter creates new controls at run time using control arrays. At design time, one control representing each column in the expense rows is placed on the expense form. The Index properties of these controls are set to 0. For example, the Date field on the left is represented by a text box named DateText. The application refers to the initial control, which has Index 0, as DateText(0). At design time, this control and the others with Index 0 can be seen within the ScrollArea in the Visual Basic development environment. At run time the application can create other controls similar to these but with new indexes using the Load statement. The following code creates a new control named DateText(1). Load DateText(1) When the control is first created, it has most of the same property values as the original DateText(0). The new controls Visible property, however, is set to false. The application can reposition the control and make other changes before it makes the control appear by setting its Visible property to true. The Load command creates new combo boxes without any list choices. After creating a new combo box, the program must add choices to it using the controls AddItem method. If the list for the new combo box should be the same as the list used by the control with index 0, the program can copy the list using code similar to the following:
For i = 0 To CategoryCombo(0).ListCount - 1
CategoryCombo(Index).AddItem CategoryCombo(0).List(i)
Next i
When a program creates a new control using the Load statement, Visual Basic adds the control to the end of the forms tab order. Sometimes this may not be a very good position for the control. In ExpenseReporter it would be best if the new expense rows were adjacent to each other in the tab order. The user should be able to tab from the to date field to the first field in the first expense row. The tab key should then move the user through the expense rows in order. Tabbing out of the last expense field in the last row should place the input focus in the Prepaid field. When a program creates a new control, it can change the controls tab order by setting its TabIndex property. The program sets this property to indicate the position in the tab order that the control should have. Controls with larger TabIndex values are bumped up one position to make room for the new control. ExpenseReporter uses subroutine MakeRow to create a new row of expense fields. This routine creates the new fields and sets their TabIndex values so they lie at the proper position in the tab order. It then creates the list of choices for the new CategoryCombo control. Next it calls subroutine SetDescrComboChoices to initialize the choices available for the Description combo box based on the value initially selected in the Category combo box. It positions the new controls below the controls in the previous row and makes the ScrollArea control large enough to hold the new row. Finally, MakeRow calls ResetScrollbar to set the scroll bars Min, Max, SmallChange, and LargeChange values based on the new size of ScrollArea.
Sub MakeRow(Index As Integer)
Dim top_value As Integer
Dim i As Integer
Dim prev_tab As Integer
Load the controls.
Load DateText(Index)
Load LocationText(Index)
Load CategoryCombo(Index)
Load DescrCombo(Index)
Load AmountText(Index)
Set tab indexes for the new controls.
prev_tab = AmountText(Index - 1).TabIndex
DateText(Index).TabIndex = prev_tab + 1
LocationText(Index).TabIndex = prev_tab + 2
CategoryCombo(Index).TabIndex = prev_tab + 3
DescrCombo(Index).TabIndex = prev_tab + 4
AmountText(Index).TabIndex = prev_tab + 5
Create the list values for the combos.
For i = 0 To CategoryCombo(0).ListCount - 1
CategoryCombo(Index).AddItem _
CategoryCombo(0).List(i)
Next i
SetDescrComboChoices Index
Blank the new controls.
ClearRow Index
Give the row the correct top.
top_value = DateText(Index - 1).Top + _
DateText(Index - 1).Height + GAP
DateText(Index).Top = top_value
LocationText(Index).Top = top_value
CategoryCombo(Index).Top = top_value
DescrCombo(Index).Top = top_value
AmountText(Index).Top = top_value
Make sure the scrolling area is big enough.
ScrollArea.Height = DateText(Index).Top + _
DateText(Index).Height + GAP
Display the controls.
DateText(Index).Visible = True
LocationText(Index).Visible = True
CategoryCombo(Index).Visible = True
DescrCombo(Index).Visible = True
AmountText(Index).Visible = True
Reset the scrollbar parameters.
ResetScrollbar
End Sub
Enhancing Field NavigationExpenseReporters scrolling area contains a set of controls arranged in rows and columns. This arrangement creates one new field navigation opportunity and one new challenge. First, the challenge. Suppose the form contains some rows of controls that lie below the visible part of the scrolling area. If the user clicks on the last amount field and then presses the Tab key, the input focus moves to the Date field in the next row. That row is not visible because it lies below the bottom of the Viewport, so the user cannot see where the focus has gone. ExpenseReporter makes the field show itself in the controls GotFocus event handler. When the input focus moves to the field, the GotFocus event handler checks the controls position in the ScrollArea to see if it is visible. If it is not, it adjusts the scroll bars Value property to move the control into view. The following GotFocus event handler for the expense Date field invokes subroutine CheckScrollingTop to ensure that the scrolling area displays a certain row. The GotFocus event handlers for the other expense fields are similar. CheckScrollingTop determines the minimum and maximum values the scroll bar can have and still keep the row visible. If the scroll bars current Value property is outside this range, the subroutine adjusts it.
Private Sub DateText_GotFocus(Index As Integer)
CheckScrollingTop Index
End Sub
Sub CheckScrollingTop(Index As Integer)
Dim min_value As Single
Dim max_value As Single
If there are no scroll bars, everything
is visible.
If Not ScrollBar.Visible Then Exit Sub
max_value = DateText(Index).Top
min_value = DateText(Index).Top + _
DateText(Index).Height - _
Viewport.ScaleHeight
See if the row is off the top.
If ScrollBar.Value > max_value Then _
ScrollBar.Value = max_value
See if the row is off the bottom.
If ScrollBar.Value < min_value Then _
ScrollBar.Value = min_value
End Sub
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|