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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jrandallsextonCommented:
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
fulscherCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.