|
Mit der Tabulator-Taste kann der Anwender gewöhnlich den Fokus von einem auf einem Form platzierten Steuerelement zum nächsten in der TabIndex-Reihenfolge verschieben. Hält er zusätzlich die Unschalt-Taste niedergedrückt, erfolgt die Verschiebung des Fokus in umgekehrter Richtung. Auch wenn eines dieser Steuerelemente ein UserControl ist, funktioniert die Verschiebung des Fokus ebenso zu auf ihm platzierten weiteren Steuerelementen - zumindest in Vorwärts-Richtung: Das UserControl selbst erhält nicht den Fokus, sondern das erste Steuerelement mit dem niedrigsten TabIndex unter den Steuerlementen des UserControls. Obwohl Sie beim Rückwärtsgang mit der Umschalt-Taste vielleicht erwarten, dass hierbei das UserControl-Steuerelement mit dem höchsten TabIndex zuerst den Fokus erhalten würde, erhält auch hierbei das Steuerelement mit dem niedrigsten TabIndex den Fokus - die übrigen Steuerelemente des UserControls werden beim Rückwärtsgang einfach übersprungen.
Obwohl das UserControl selbst nicht den Fokus erhält, wird bei ihm beim "Einsprung" trotzdem das EnterFocus-Ereignis ausgelöst. Dies gibt Ihnen die Möglichkeit, in diesem Ereignis zu prüfen, ob die Umschalt-Taste niedergedrückt gewesen war. War dies der Fall, liefert die API-Funktion GetKeyState zum Tasten-Code der Umschalt-Taste (vbKeyShift) einen Wert, der größer als &HF000& ist. Somit können Sie dann den Fokus nachträglich per Code auf das Steuerelement mit dem höchsten TabIndex unter den UserControl-Steuerlementen verschieben. Und sobald dieses den Fokus erhalten hat, funktioniert der Rückwärtsgang auch wieder einwandfrei innerhalb der UserControl-Steuerlemente.
Zusätzlich sollten Sie auch noch auf die gleiche Weise prüfen, ob der Fokus-Einsprung ins UserControl überhaupt über die Tabulator-Taste erfolgt ist (siehe auch: "Woher kommst Du gegangen?").
Einen kleinen Haken hat dieses Verfahren allerdings noch: Das UserControl-Steuerelement mit dem niedrigsten TabIndex erhält trotzdem kurzzeitig den Fokus - auch wenn dies gar nicht sichtbar wird. Falls die Fokus-Ereignisse GotFocus und LostFocus (und gegebenenfalls auch das Validate-Ereignis) für dieses erste Steuerelement von Bedeutung sein sollten, müssen Sie in einer UserControl-weit gültigen Flag-Variablen signalisieren, dass der Fokus-Erhalt in diesem Fall nichts bewirken (nicht gültig) sein soll. Dazu fügen Sie in diesen Ereignissen eine Prüfung der Flag-Variablen ein und führen den eigentlichen Code in den Ereignissen nur dann aus, wenn sie nicht gesetzt ist. Im LostFocus-Ereignis des ersten Steuerelements wird die Flag-Variable wieder zurückgesetzt.
Der folgende Code für das EnterFocus-Ereignis des UserControls geht davon aus, dass Sie nicht festlegen wollen, welches das in der TabIndex letzte Steuerelement sein wird. Wenn Sie dieses festlegen können, können Sie sich den Code zur Ermittlung desselben natürlich sparen (diese Variante finden Sie am Schluss des Artikels).
Private Declare Function GetKeyState Lib "user32" _
(ByVal VirtualKeyCode As Long) As Long
Private mFocusBack As Boolean
Private Sub UserControl_EnterFocus()
Dim nControl As Control
Dim nLastControl As Control
Dim nMaxTabIndex As Integer
mFocusBack = False
If (GetKeyState(vbKeyTab) And &HF000&) = &HF000& Then
If (GetKeyState(vbKeyShift) And &HF000&) = &HF000& Then
nMaxTabIndex = -1
For Each nControl In Controls
With nControl
If .TabIndex > nMaxTabIndex Then
nMaxTabIndex = .TabIndex
If .Visible And .Enabled Then
Set nLastControl = nControl
End If
End If
End With
Next
If Not (nLastControl Is Nothing) Then
mFocusBack = True
nLastControl.SetFocus
End If
End If
End If
End Sub
Private Sub ControlMitNiedrigstemTabIndex_GotFocus()
If Not mFocusBack Then
' Code
End If
End Sub
Private Sub ControlMitNiedrigstemTabIndex_LostFocus()
If mFocusBack Then
mFocusBack = False
Else
' Code
End If
End Sub
Private Sub ControlMitNiedrigstemTabIndex_Validate(Cancel As Boolean)
If Not mFocusBack Then
' Code
End If
End Sub
Die Variante mit Festlegung des Steuerelements mit dem höchsten TabIndex:
Private Sub UserControl_EnterFocus()
mFocusBack = False
If (GetKeyState(vbKeyTab) And &HF000&) = &HF000& Then
If (GetKeyState(vbKeyShift) And &HF000&) = &HF000& Then
mFocusBack = True
ControlMitHoechstemTabIndex.SetFocus
End If
End If
End Sub
|