Previous | Index | Next 

[PRB] Setting the TabIndex property in VB.NET doesn’t affect the TabIndex of other controls

VB6 and VB.NET handle the TabIndex property differently. Under VB6 all controls on the form have a unique TabIndex value: if you assign the TabIndex property of a control using a value that is already used by another control on the same form then VB6 shifts all TabIndex values accordingly to preserve uniqueness. By contrast, VB.NET allows two controls to have equal TabIndex values and no reordering occurs when you assign a TabIndex value that is already used. Also, in .NET the TabIndex of the container control is also taken into account when establishing the actual order in which controls are visited by hitting the Tab key.

In most cases the difference doesn’t prevent migrated VB.NET applications from working correctly. At times, however, the original VB6 code relies on this detail for proper working. For example, VB6 developers have two ways to programmatically select which control has the focus when a form becomes visible: they can use the SetFocus method or can assign the control’s TabIndex to zero. Only the first method is guaranteed to work in converted VB.NET applications, thus you might need to edit the original VB6 code accordingly.

In some cases, not even using the SetFocus method works correctly inside converted applications. For example, assume that you have a VB6 UserControl that includes this code to select which child control has the focus when the UserControl becomes visible or has the focus:

        Private Sub UserControl_EnterFocus()
            Text1.SetFocus
        End Sub

When the UserControl is converted to VB.NET, however, the SetFocus method is ignored and the focus is given to the child control whose TabIndex is equal to zero, in all cases. As explained previously, you can’t solve this problem by replacing the SetFocus method with an assignment to the Text1.TabIndex property, as in:

        ' this code doesn't work in converted VB.NET applications
        Private Sub UserControl_EnterFocus()
            Text1.TabIndex = 0
        End Sub

In fact, VB.NET doesn’t reorder controls when you change the TabIndex property. To offer a workaround for this issue we have included the SetTabIndex6 method in the VBMigrationPartner_Support module. The method has the following syntax:

        SetTabIndex6 control, newTabIndexValue [,setFocusNow]

You can pass True in the third argument to force a SetFocus method on the control passed in the first argument. You can now rewrite the original VB6 code as follows:

        ' this code works in converted VB.NET applications
        Private Sub UserControl_EnterFocus()
            SetTabIndex6 Text1, 0, True
        End Sub

The VB.NET version of the SetTabIndex6 method correctly shifts the TabIndex property of all the controls in the same container, thus simulating more closely the behavior under VB6. Or you can drop the VBMigrationPartner_Support module and use a ReplaceStatement pragma:

        ' this code works in converted VB.NET applications
        Private Sub UserControl_EnterFocus()
            '## ReplaceStatement SetTabIndex6 Text1, 0, True
            Text1.SetFocus
        End Sub

Keep in mind, however, that the SetTabIndex6 method affects the TabIndex property only of the controls that are in the same container as the control passed in the first argument. If the form or the UserControl contains nested containers you might need to invoke it multiple times, one for each container.

 

Previous | Index | Next