Solved

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

Posted on 2004-10-29
520 Views
Last Modified: 2012-05-05
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?
0
Question by:haneri
    4 Comments
     
    LVL 4

    Assisted Solution

    by:jrandallsexton
    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
     

    Author Comment

    by:haneri
    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
     
    LVL 4

    Expert Comment

    by:jrandallsexton
    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
     
    LVL 12

    Accepted Solution

    by:
    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

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Lean Six Sigma Project Manager Certification

    There are many schools of thought around successful project management, but few as highly regarded as the Six Sigma and Lean methods. With 37 hours of learning, this training will explain concrete processes for increasing efficiency and limiting wasted time and effort.

    Article by: jpaulino
    XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
    Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
    Hi everyone! This is Experts Exchange customer support.  This quick video will show you how to change your primary email address.  If you have any questions, then please Write a Comment below!
    Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

    846 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    7 Experts available now in Live!

    Get 1:1 Help Now