• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 949
  • Last Modified:

WinForms Automatically Set Cursor Position to 0 as user tabs thru a set of text boxes?

I have VB.Net Applicaition.   It has hundreds of textboxes with a variety of different length strings.   Is there a way to automatically set the cursor postion to the beginning of the string as a user tabs thru them?


I have the code on the form that captures the Enter Key and converts it to a Tab key.   I was thinking that in here, I could put in the code.... If texttbox Control then move cursor to the front of the string.

I am trying to avoid placing the code in each of the 100 textboxes on Enter property.

Thanks.

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Enter Then
            Dim ctl As Control = Me.ActiveControl
            If Not (ctl Is Nothing) Then
                If (TypeOf ctl Is TextBox) Or (TypeOf ctl Is CheckBox) Or (TypeOf ctl Is ComboBox) Then
                    SendKeys.Send("{TAB}")
 
                    Return True
                    Exit Function
                End If
            End If
        End If
  Return MyBase.ProcessCmdKey(msg, keyData)

Open in new window

0
rrowe68
Asked:
rrowe68
  • 7
  • 5
  • 4
1 Solution
 
Snarf0001Commented:
Don't think there's a way like your trying.  In the function override you have, the code will execute before the next control gets the focus, so you'd have to loop through and put in logic to find out what would get focus next.

Can i ask why you don't want to hook up events for each of them?  Is it just the manual process of doing it?  If so, you could just loop through the controls on form load and attach the handlers then.
May be a small performance hit, but it would pale in comparison to trying to figure out the next control on each tab hit.
0
 
jpaulinoCommented:
Try this way:
    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Enter Then
            If TypeOf Me.ActiveControl Is TextBox Then
                Dim tb As TextBox = DirectCast(Me.ActiveControl, TextBox)
                SendKeys.Send("{TAB}")
                tb.Select(0, 0)
                Return True
            End If
        End If
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

Open in new window

0
 
rrowe68Author Commented:
I agree it is manual and I can do it.... Just being lazy to see if there is a simpler way.

Is there a way to 'loop through the controls on form and load / attach handlers".

I know how to manually do one at design time, but not multiple at design/run time.  I am a little new to VB.NET.

Thanks for the help.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Snarf0001Commented:
np, use something like this:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each ctl As Control In Me.Controls
            If (TypeOf ctl Is TextBox) Then
                AddHandler ctl.Enter, New EventHandler(AddressOf TextBox_Enter)
            End If
        Next
    End Sub
 
    Private Sub TextBox_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)
 
        Dim target As TextBox = CType(sender, TextBox)
        target.SelectionStart = 0
 
    End Sub

Open in new window

0
 
Snarf0001Commented:
Note that if the textboxes aren't all directly on the form (ie they're contained in a panel or other container), you'll have to create a resursive function to loop through all child controls.
0
 
jpaulinoCommented:
>> Don't think there's a way like your trying.  In the function override you have, the code will execute before the next control gets the focus, so you'd have to loop through and put in logic to find out what would get focus next.
@Snarf0001,
When you do the TAB in the ProcessCmdKey the cursor moves to the next control. You then check if it's a textbox and place the cursor in the beginning.
There's no problem with that and you don't need to addhandler to allot of controls and use recursive functions.
@rrowe68,
Small change to my code snippet

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Enter Then
            SendKeys.Send("{TAB}")
 
            If TypeOf Me.ActiveControl Is TextBox Then
                Dim tb As TextBox = DirectCast(Me.ActiveControl, TextBox)
                tb.Select(0, 0)
            End If
            Return True
 
        End If
 
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

Open in new window

0
 
rrowe68Author Commented:
jPaulino -
That half way works, but it doesn't send then cursor to the next text box in the tab order.  It just puts the cursor at the beginning of the current textbox without moving to the next.

Thanks.
0
 
jpaulinoCommented:
>> That half way works, but it doesn't send then cursor to the next text box in the tab order.  It just puts the cursor at the beginning of the current textbox without moving to the next.

Have you tried the last update ?
0
 
Snarf0001Commented:
jpaulino, the tab sendkeys moves focus to the next textbox, but the activecontrol doesn't reach that point yet until sendkeys has a chance to get there.

THe selection is going to be applied to the currently focused tb before the sendkeys are sent.

Try it out in a winform, and you'll see that the tb that the cursor jumps to doesn't move to the start.
0
 
jpaulinoCommented:
>> Try it out in a winform, and you'll see that the tb that the cursor jumps to doesn't move to the start.
I'm using a winform VS 2008 and work fine for me!
Please ignore my first snippet. It was not tested correctly.
0
 
Snarf0001Commented:
I'm using the same thing, and the cursor only moves the start of the tb on the following pass through.
0
 
Snarf0001Commented:
If you set up the following code with a mock log textbox, you'll see that the casting / index setting is taking place before the sent tab character is received, and the carat is being set on the tb that's about to be move off of.


    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = Keys.Enter Then
            txtLog.AppendText("about to send tab" & Environment.NewLine)
                SendKeys.Send("{TAB}")
 
            txtLog.AppendText("tab sent" & Environment.NewLine)
            If TypeOf Me.ActiveControl Is TextBox And Not (Me.ActiveControl Is txtLog) Then
                Dim tb As TextBox = DirectCast(Me.ActiveControl, TextBox)
                tb.Select(0, 0)
                txtLog.AppendText("position set" & tb.Name & Environment.NewLine)
            End If
            Return True
 
        ElseIf keyData = Keys.Tab Then
 
            txtLog.AppendText("tab received" & Environment.NewLine)
            Dim s As String = "5"
 
        End If
 
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

Open in new window

0
 
rrowe68Author Commented:
I am getting the same thing as Snarf.

It isn't leaving the textbox it is on.

I am using VS 2008 also.

Any thoughts?
0
 
jpaulinoCommented:
After a few tests I think I understand the problem. It only see it and understand it on textboxes with multiline set to true.
I didn't tried with :)
Add a Application.DoEvents()  immediately after the sendkeys method to let the system do the action.
0
 
Snarf0001Commented:
On that point I'll agree now.

That was my problem, that the tab key send was getting hung up in the message queue and not processing until the function ended.

Forgot about the handy .DoEvents().
0
 
rrowe68Author Commented:
That works!!!
Thanks - it saved me a ton of time!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 7
  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now