In Windows Forms is there an autotab capability
It existed in MFC where when typing into an Edit control (textBox), once the max number of characters for the control was exceeded, the focus went to the next control and the characters were entered there. I often see the feature while typing Microsoft serial numbers during software installations.

Windows Forms autotab
Brack0893
Thanks. I'll post the code when I have it finished.
fddsfsdf
In other words, to use SendKeys, you either must not care if the keystrokes go to the wrong app, or constantly check to see if the app is correct and switch back if it's not. Neither is a perfect solution.
So, just for fun, I created a new class and added this functionality:
Public Class TextBoxAutoTab
Inherits TextBox
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
MyBase.OnTextChanged(e)
If Me.TextLength = Me.MaxLength Then
Dim ctl As Control = Me.Parent.GetNextControl(Me, True)
If Not ctl Is Nothing Then
If ctl.CanFocus Then
ctl.Focus()
End If
End If
End If
End Sub
End Class
You could obviously add more functionality (for example, have the code look for the next control that can receive the focus, rather than simply giving up if the next control cannot).
To use this, you can either create a real control (so you can add the control to the toolbox) or, the simple solution is just to open the hidden region of your form's code and replace the pertinent instances of System.Windows.Forms.TextBox with the name of this class (which I called TextBoxAutoTab). Worked great, in my limited tests.
Spktrader
Jose Lucas
Also, is there a way to know if text in a TextBox is selected at all
Ned Radenovic
Here's my email if you need more info, minus the 123 (an idea gleaned from your web page):
<A HREF="mailto:lerdmann@123state.nd.us">lerdmann@123state.nd.us</A>
Brian M. Reisman
I did have to change CanFocus to CanSelect. I looped through the controls till I found the first selectable one. It seems that some controls can screw up the works. The problem occured with a PictureBox on the form (It returned true for CanFocus in v1.0).
'*** Not sure if VB loop will short circut on 'ctl is nothing' -> Ken will know.
Dim ctl as Control = Me.Parent.GetNextControl(Me, True)
Do Until ctl is nothing or ctl.CanSelect or ctl = Me
ctl = Me.Parent.GetNextControl(ctl,True)
Loop
If not ctl is nothing
ctl.Focus()
End If
Another thought
===========
I did not use the KeyPress event because it takes a lot more code to handle the event. It is fired for control keys and such. TextChanged will also handle copy/paste events.
Your other question
=============
SelectionText, SelectionStart and SelectionLength are the properties you can use to see if the TextBox has anything selected.
abyss_thomas
JackS
It would be simplistic to emulate using the TextChanged event and SendKeys.
private void textBox1_TextChanged(object sender, System.EventArgs e)
{
if (textBox1.Text.Length == textBox1.MaxLength)
{
SendKeys.Send("\t");
}
}
Rory Hudson
jlandry
Using the TextChanged event, there is no way to know when the length has been exceeded, but that is something I can do in KeyPress.
Here is the code as I've written it, and it does exactly what I want:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (Text.Length == MaxLength) // we have exceeded the MaxLength
{
string keyEntered = "";
keyEntered = e.KeyChar.ToString();
keyEntered = keyEntered.Substring(0,1); // store the first keystroke
Regex rx = new Regex("[0-9a-fA-F]");
bool isValid = rx.IsMatch(keyEntered); // make sure it's alphanumeric
if (isValid)
{
e.Handled = true;
SendKeys.SendWait("\t"); // tab to next control
SendKeys.Send(keyEntered); // send the keystroke
}
}
base.OnKeyPress(e);
}
I can see how the SendKeys class can be problematic. Thanks for the info.
Kuma1
I did add a couple of properties, the AutoTab property that allows you to turn off the functionality, and the SelAllOnEnter property will select the text for you when you enter the TextBox.
JCL
Kurniawan
I do have one final suggestion, however. No need to use RegEx (although since this only occurs once per input control, it hardly makes any difference). But you can get away with this in a more simple manner, using the Char.IsLetterOrDigit method, and the TextLength property:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (TextLength == MaxLength) // we have exceeded the MaxLength
{
if (Char.IsLetterOrDigit(e.KeyChar))
{
e.Handled = true;
SendKeys.SendWait("\t"); // tab to next control
SendKeys.Send(e.KeyChar.ToString()); // send the keystroke
}
}
base.OnKeyPress(e);
}
slein
base.OnKeyPress(e)
knows what to do with the invalid characters (punctuation, spaces, etc.). Otherwise, you could easily exceed MaxLength and continue on and on. Paste could also make your system jump over MaxLength.
I do like that your code does not fail when the user hits tab at the expected time.
P.S.
Are you sure that the user cannot insert a new character between the two SendKeys calls Some people can really fill a buffer. Maybe
SendKeys.SendWait("\t" + keyEntered);
would be safer.