How do I change focus within event handler without raising additional events

I have a vb.net form that I want to be able to shift focus to a control (not the next one in tab order) based on the user input in the current control.  As an simplified example I’ve created a form with three textbox controls and the following event handlers.  


Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
    Debug.WriteLine(sender.name & " Enter Event")
End Sub

Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave, TextBox3.Leave
    Debug.WriteLine(sender.name & " Leave Event")
End Sub

Private Sub TextBox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus, TextBox2.LostFocus, TextBox3.LostFocus
     Debug.WriteLine(sender.name & " Lost Focus Event")
End Sub

Private Sub Assign_Focus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox2.Leave
     Debug.WriteLine(sender.name & " LEAVE EVENT")
     If TextBox2.Text = "a" Then
        Debug.WriteLine("  About to request change focus")
        TextBox1.Focus()
        Debug.WriteLine("  After focus change request")
     End If
End Sub

I ran the form tabbing at textbox1, entering “a” in textbox2 and then hit tab again.  The output from the Debug.Writeline statements is as follows:

TextBox1 Enter Event
TextBox1 Leave Event
TextBox2 Enter Event
TextBox1 Lost Focus Event
TextBox2 LEAVE EVENT
  About to request change focus
TextBox2 Lost Focus Event
TextBox2 LEAVE EVENT
  About to request change focus
  After focus change request
TextBox1 Enter Event
  After focus change request
TextBox1 Enter Event

Note that TextBox1.Focus causes a duplication of events

Is there a clean way of accomplishing a control focus shift without causing extra events or at least not having to remove the handlers of those events and later adding them back?
haneriAsked:
Who is Participating?
 
fulscherConnect With a Mentor Commented:
The way I usually do it is as follows:

Dim ChangeFocusCall as Boolean = FALSE  ' skip events if we manually change focus

Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
    if ChangeFocusCall Then Exit Sub
    Debug.WriteLine(sender.name & " Enter Event")
End Sub

Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave, TextBox3.Leave
    if ChangeFocusCall Then Exit Sub
    Debug.WriteLine(sender.name & " Leave Event")
End Sub

Private Sub TextBox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus, TextBox2.LostFocus, TextBox3.LostFocus
     if ChangeFocusCall Then Exit Sub
     Debug.WriteLine(sender.name & " Lost Focus Event")
End Sub

Private Sub Assign_Focus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox2.Leave
     Debug.WriteLine(sender.name & " LEAVE EVENT")
     If TextBox2.Text = "a" Then
        Debug.WriteLine("  About to request change focus")
        ChangeFocusCall = TRUE
        TextBox1.Focus()
        Debug.WriteLine("  After focus change request")
     End If
End Sub

However, this usually requires some fiddling to get it right - because of multiple events being called.

HTH, J
0
 
jrandallsextonConnect With a Mentor Commented:
haneri:

As far as I know, you will have to unhook and rehook the events if you don't want them to fire.  I've had to do it before myself.

Wrap your hooks and unhooks into a function and make it easy on yourself.

'or whatever events you'd like to hook/unhook
Private Sub HookMyTextBox(hookEvents As Boolean)
If hookEvents Then
   Addhandler TextBox1.Enter, AddressOf TextBox_Enter
   Addhandler TextBox1.Leave, AddressOf TextBox_Leave
   Addhandler TextBox1.LostFocus, AddressOf TextBox_LostFocus
Else
   RemoveHandler TextBox1.Enter, AddressOf TextBox_Enter
   RemoveHandler TextBox1.Leave, AddressOf TextBox_Leave
   RemoveHandler TextBox1.LostFocus, AddressOf TextBox_LostFocus
EndIf
0
 
haneriAuthor Commented:
I like your method of controlling adding and removing the event handlers (thanks) but I thought (and was hoping) there was some other way to "one time" cancel these events and jump to the execution of events of the new control where the focus was shifted.  Maybe there is another solution out there.
0
 
jrandallsextonCommented:
I'd be interested in seeing it too.

I'm sorry that I posted exactly what you specifically asked not to have - I just don't know any other way of doing it.

Maybe someone else will have something to add.

Good luck!
0
All Courses

From novice to tech pro — start learning today.