How to make Enter on a TextBox act as TAB button - c#

I've several textboxes. I would like to make the Enter button act as Tab. So that when I will be in one textbox, pressing Enter will move me to the next one. Could you please tell me how to implement this approach without adding any code inside textbox class (no override and so on if possible)?

Here is the code that I usually use.
It must be on KeyDown event.
if (e.KeyData == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
UPDATE
Other way is sending "TAB" key! And overriding the method make it so easier :)
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Enter))
{
SendKeys.Send("{TAB}");
}
return base.ProcessCmdKey(ref msg, keyData);
}

You can write on the keyDown of any control:
if (e.KeyCode == Keys.Enter)
{
if (this.GetNextControl(ActiveControl, true) != null)
{
e.Handled = true;
this.GetNextControl(ActiveControl, true).Focus();
}
}
GetNextControl doesn't work on Vista.
To make it work with Vista you will need to use the code below to replace the this.GetNextControl...:
System.Windows.Forms.SendKeys.Send("{TAB}");

You don't need to make an "enter event handler"
All you need to do is make a "central" KeyDown event:
example
private void General_KeyDown(object sender, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (this.GetNextControl(ActiveControl, true) != null)
{
e.Handled = true;
this.GetNextControl(ActiveControl, true).Focus();
}
}
}
Then all you have to do is go to designer select all textboxes you wish to cycle through with EnterKey (select them by holding down Ctrl and clicking on textbox with the mouse) then go to Events(thunder like button), search Keydown event and type inside General_KeyDown. Now all your selected Textboxes will have the same keydown event :) This makes everything muuuuch much easier, cause imagine a form with 100 textboxes and you want to cycle through all with enter.... making an apart event for each texbox is... well not a proper way to make a program, it ain't neat. Hope it helped!!
Blockquote

This worked for me
if (e.Key == Key.Enter)
((TextBox)sender).MoveFocus(new TraversalRequest(new FocusNavigationDirection()));

It is important to note that if you will get an annoying "ding" or warning sound each time that the control is expecting an associated button control and e.Handled = true isn't always the answer to rid yourself of the noise/sound/ding.
If the control (i.e. single-line textbox) is expecting an associated button to 'ENTER' your entry, then you must also deal with the 'missing' control.
e.Handled = e.SuppressKeyPress = true;
This may be helpful when getting rid of the 'ding' sound.
For what it's worth- in my circumstance my users needed to use the "ENTER KEY" as we were transitioning from a terminal/green-screen application to a windows app and they were more used to "ENTER-ing" through fields rather than tabbing.
All these methods worked but still kept the annoying sound until I added e.SuppressKeyPress.

If you define Tab Order of all controls and make Form.KeyPreview = True, only need this:
Private Sub frmStart_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
System.Windows.Forms.SendKeys.Send("{TAB}")
End If
End Sub

I use this code in one of the text box keydown event
if (e.KeyData == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
Unable handle this keydown event for all text boxes in my form. Suggest something. Thanks

I don't do it at the form level. I create a single method that I share across all my inputs KeyDown event that I want to do this with (with one exception):
private void alltextBoxes_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
}
catch
{
}
}
If I'm writing a control that I want to use in other applications, I give the last input its own method like this:
private void lastinput_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
System.Windows.Forms.SendKeys.Send("{TAB}");
}
}
catch
{
}
}
Otherwise, the control just loops inside itself when you try to run it in another project. You could use the second way everywhere but I think the 1st is the preferred way.

For those of you that code in vb...
Public Class NoReturnTextBox
Inherits System.Windows.Forms.TextBox
Const CARRIAGE_RETURN As Char = Chr(13)
' Trap for return key....
Private Sub NoReturnTextBox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar = CARRIAGE_RETURN Then
e.Handled = True
System.Windows.Forms.SendKeys.Send(vbTab)
End If
End Sub
End Class

This is the solution I use for VB.NET
Set Keypreview=True in your form properties.
Put this code in form keydown event:
If (e.KeyData = Keys.Enter) Then
'for any multiline control, you have to exit to let multiline 'textbox intro 'keypressing makes line skips.
If ActiveControl.Name = txtMyMutilineTextBox.Name Then Exit Sub
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, True, True, True, True)
End If
Enjoy !!!!
Xabier Aberasturi Larruzea

This is better because when enter u can do focus the next tab.. U need setting TAB Order first
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Enter))
{
SelectNextControl(ActiveControl, true, true, true, true);
}
return base.ProcessCmdKey(ref msg, keyData);
}

Taking a wild guess:
// on enter event handler
parentForm.GetNextControl().Focus();

I would combine what Pharabus and arul answered like this:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == ‘\r’)
{
e.Handled = true;
parentForm.GetNextControl().Focus()
}
}
Let me know if this helps! JFV

Related

How to prevent controls from capturing KeyDown events while a modal form is open?

I have a form with CancelButton and AcceptButton (named btnCancel and btnOK). And I have some ComboBoxes as input fields.
ComboBoxes prevent my AcceptButton and CancelButton to receive Escape and Enter keys, so I added this code to KeyDown event for all fields:
if (e.KeyData == Keys.Escape)
{
ComboBox field = (ComboBox)sender;
if ((field.DropDownStyle == ComboBoxStyle.Simple) || (!field.DroppedDown))
{
e.SuppressKeyPress = true;
btnCancel.PerformClick();
}
}
else if (e.KeyData == Keys.Enter)
{
ComboBox field = (ComboBox)sender;
if ((field.DropDownStyle == ComboBoxStyle.Simple) || (!field.DroppedDown))
{
e.SuppressKeyPress = true;
btnOK.PerformClick();
}
}
This is the code in Clicked event of OK button:
if (!changesAreSaved)
{
SaveChangesToNode();
}
List<int> invalidIndices = ValidateAndRefineNodes(true);
if (invalidIndices.Count == 0)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show(this, "Enter correct values for all fields before you press OK.", "Cannot Save Information",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Everything is OK but when a ComboBox has Focus and I press Enter key on my keyboard, btnOK_Clicked calls Fields_KeyDown again only when it shows its MessageBox (on else part of if). Exactly right after MessageBox.Show(...) is being called, KeyDown event is being called for second time without any reason.
This is Call Stack for first call:
And this is for second:
Second call should not occur at all. In second Call Stack, first btnOK_Click (third line) again calls Fields_KeyDown (second line) from MessageBox.Show(...). How is this possible? I'm confused...
Call Stack for second call with External Code visible:
You cannot correctly process Escape and Enter key in KeyDown event because they are handled during the keyboard preprocessing phase - Control.IsInputKey and Control.ProcessDialogKey. Normally controls do that for you, but looks like there is a bug in ComboBox implementation when DropDownStyle is Simple.
To get the desired behavior, create and use your own ComboBox subclass like this
public class MyComboBox : ComboBox
{
protected override bool IsInputKey(Keys keyData)
{
if (DropDownStyle == ComboBoxStyle.Simple)
{
switch (keyData & (Keys.KeyCode | Keys.Alt))
{
case Keys.Return:
case Keys.Escape:
return false;
}
}
return base.IsInputKey(keyData);
}
}
P.S. And of course don't forget to remove your KeyDown event handlers.
While I have no idea about the main reason behind this behavior.
But in this situation obviously KeyDown event triggers 2 times. (Set a breakpoint and you will see.)
Since you need to handle it in code, You can try this to neglect one of Enter keys:
bool handled = true;
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
/*Prevent handling the Enter key twice*/
handled = !handled;
if(handled)
return;
//Rest of logic
//OkButton.PerformClick();
}
}

Why AcceptButton is being called twice? [duplicate]

I have a form with CancelButton and AcceptButton (named btnCancel and btnOK). And I have some ComboBoxes as input fields.
ComboBoxes prevent my AcceptButton and CancelButton to receive Escape and Enter keys, so I added this code to KeyDown event for all fields:
if (e.KeyData == Keys.Escape)
{
ComboBox field = (ComboBox)sender;
if ((field.DropDownStyle == ComboBoxStyle.Simple) || (!field.DroppedDown))
{
e.SuppressKeyPress = true;
btnCancel.PerformClick();
}
}
else if (e.KeyData == Keys.Enter)
{
ComboBox field = (ComboBox)sender;
if ((field.DropDownStyle == ComboBoxStyle.Simple) || (!field.DroppedDown))
{
e.SuppressKeyPress = true;
btnOK.PerformClick();
}
}
This is the code in Clicked event of OK button:
if (!changesAreSaved)
{
SaveChangesToNode();
}
List<int> invalidIndices = ValidateAndRefineNodes(true);
if (invalidIndices.Count == 0)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show(this, "Enter correct values for all fields before you press OK.", "Cannot Save Information",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Everything is OK but when a ComboBox has Focus and I press Enter key on my keyboard, btnOK_Clicked calls Fields_KeyDown again only when it shows its MessageBox (on else part of if). Exactly right after MessageBox.Show(...) is being called, KeyDown event is being called for second time without any reason.
This is Call Stack for first call:
And this is for second:
Second call should not occur at all. In second Call Stack, first btnOK_Click (third line) again calls Fields_KeyDown (second line) from MessageBox.Show(...). How is this possible? I'm confused...
Call Stack for second call with External Code visible:
You cannot correctly process Escape and Enter key in KeyDown event because they are handled during the keyboard preprocessing phase - Control.IsInputKey and Control.ProcessDialogKey. Normally controls do that for you, but looks like there is a bug in ComboBox implementation when DropDownStyle is Simple.
To get the desired behavior, create and use your own ComboBox subclass like this
public class MyComboBox : ComboBox
{
protected override bool IsInputKey(Keys keyData)
{
if (DropDownStyle == ComboBoxStyle.Simple)
{
switch (keyData & (Keys.KeyCode | Keys.Alt))
{
case Keys.Return:
case Keys.Escape:
return false;
}
}
return base.IsInputKey(keyData);
}
}
P.S. And of course don't forget to remove your KeyDown event handlers.
While I have no idea about the main reason behind this behavior.
But in this situation obviously KeyDown event triggers 2 times. (Set a breakpoint and you will see.)
Since you need to handle it in code, You can try this to neglect one of Enter keys:
bool handled = true;
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
/*Prevent handling the Enter key twice*/
handled = !handled;
if(handled)
return;
//Rest of logic
//OkButton.PerformClick();
}
}

Why does the PreviewKeyDown event get called a second time when IsInputKey is set true?

VS2010 C# .Net 4.1
I am working on a form that the user must select or enter initial data in a ComboBox. Using the code below, which took some time to deduce, I enable the Edit button when the user hits the Tab key if the data is correct, otherwise the button is disabled it moves to the next button.
This code works, but a side effect is that the PreviewKeyDown event reoccurs when I set IsInputKey to true. This calls validation twice. The KeyDown event is only called once, and the IsInputKey is false again on the second call so I do need to check validation again.
I'd like to understand why and possibly avoid it.
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
if (e.KeyData == Keys.Tab) {
if (ValidationRoutine()) {
e.IsInputKey = true; //If Validated, signals KeyDown to examine this key
} //Side effect - This event is called twice when IsInputKey is set to true
}
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == Keys.Tab) {
e.SuppressKeyPress = true; //Stops further processing of the TAB key
btnEdit.Enabled = true;
btnEdit.Focus();
}
}
The why? is hard to answer, Winforms just does. First from the message loop, again from the control's message dispatcher. The event was really meant as an alternative way to implement the protected IsInputKey() method without having to override the control class. Bit of a hack, I always override and never used the event.
The better mouse trap is to override ProcessCmdKey() instead. Like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (this.ActiveControl == comboBox1 && keyData == Keys.Tab) {
if (ValidationRoutine()) {
btnEdit.Enabled = true;
btnEdit.Focus();
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}

Stop the 'Ding' when pressing Enter

I have a very simple Windows Forms Application. And, in Windows (or, atleast Windows Forms Applications), when you press Enter while inside a Single-line TextBox Control, you hear a Ding. It's an unpleasent sound, that indicated you cannot enter a newline, because it is a single-line TextBox.
This is all fine. However, in my Form, I have 1 TextBox, and a Search Button. And I am allowing the user to Perform a search by pressing Enter after they've finished typing, so they don't have to use the mouse to click the Search Button.
But this Ding sound occurs. It's very annoying.
How can we make it so just that sound doesn't play at all in my Form?
#David H - Here's how I'm detecting the enter pressing:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// Perform search now.
}
}
It works for me:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
//Se apertou o enter
if (e.KeyCode == Keys.Enter)
{
//enter key is down
this.doSomething();
e.Handled = true;
e.SuppressKeyPress = true;
}
}
The SuppressKeyPress is the really trick. I hope that help you.
Check out the Form.AcceptButton property. You can use it to specify a default button for a form, in this case for pressing enter.
From the docs:
This property enables you to designate
a default action to occur when the
user presses the ENTER key in your
application. The button assigned to
this property must be an
IButtonControl that is on the current
form or located within a container on
the current form.
There is also a CancelButton property for when the user presses escape.
Try
textBox.KeyPress += new KeyPressEventHandler(keypressed);
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true; //this line will do the trick
}
}
Just add e.SuppressKeyPress = true; in your "if" statement.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//If true, do not pass the key event to the underlying control.
e.SuppressKeyPress = true; //This will suppress the "ding" sound.*/
// Perform search now.
}
}
You can Use KeyPress instead of KeyUp or KeyDown its more efficient
and here's how to handle
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
button1.PerformClick();
}
}
and say peace to the 'Ding'
Use SuppressKeyPress to stop continued processing of the keystroke after handling it.
public class EntryForm: Form
{
public EntryForm()
{
}
private void EntryTextBox_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
}
private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
// do some stuff
}
}
}
On WinForms the Enter key causes a Ding sound because the form property AcceptButton is not specified.
If you don't need an AcceptButton the ding sound can be suppressed by setting the form KeyPreview to true and enter the following KeyPress event:
private void Form_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
e.Handled = true;
}
No matter what control is active, there will be no more ding sound when pressing the Enter key. Since the key event proccessing order is KeyDown, KeyPress and KeyUp the Enter key will still work for the KeyDown events for the controls.
I stumbled on this post while trying to handle a KeyDown this worked for me.
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
btnLogIn.PerformClick()
End If
Supressing the Key Press stops the event from being sent to the underlying control. This should work if you're manually handling everything that the enter key will be doing within that textbox. Sorry about the Visual Basic.
$("#txtSomething").keypress(function (e) {
if (e.which == 13) {
e.Handled = true; //This will prevent the "ding" sound
//Write the rest of your code
}
});
There is a very little chance anyone gets to this answer but some other answers are truly scary. Suppressing event on KeyDown kills 2 additional events in one strike. Setting e.Handled property to true is useless in this context.
The best way is to set Form.AcceptButton property to the actual Search Button.
There is also another way of utilizing Enter key - some people may want it to act as TAB button. To do that, add a new Button, set its Location property outside of the Form area (i.e. (-100, -100)) - setting Visible property to false may disable Button handlers in some cases. Set Form.AcceptButton property to your new button. In Click event handler add following code
this.SelectNextControl(ActiveControl, true, true, true, true)
Now, you may want to transfer focus only when focus it on TextBox you may want to either test ActiveControl type or use e.Supress property in event handlers of controls not meant to use Enter as TAB
That's it. You don't even need to capture e.KeyCode
Set your Search button's IsDefault property to true. This will make it a default button and it will be auto-clicked when Enter is pressed.
Well I lived with this problem long enough and looked it up here.
After thinking about this for quite some time and wanting the simplest way to fix it I came up with the easiest but not so elegant way to fix it.
Here is what I did.
Put 2 invisible buttons "Ok" and "Cancel" on the form.
Set the AcceptButton and CancelButton Property on the form to the invisible buttons.
Added no code to the buttons!
This solved all the secondary problems listed in this thread including the ToolStripMenu. My biggest complaint was the BindingNavigator, when I would enter a record number into the Current position to navigate to and pressed enter.
As per the original question in which the programmer wanted a search function when the enter button was pressed I simply put the search code in the invisible OK Button!
So far this seems to solve all problems but as we all know with Visual Studio, something will probably crop up.
The only other possible elegant way I could think of would be to write a new keystroke handling class which is way to much work for most of my projects.
You can set your textbox multi-line to true then handle the Enter key press.
private void yourForm_Load(object sender, EventArgs e)
{
textBox1.Multiline = true;
}
//then write your TextBox codes
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// doSomething();
}
}
i changed the textbox properties for an multiline textbox and it works for me.
Concerning the e.SuppressKeyPress = true; solution, it works fine by itself. Setting SuppressKeyPress to true also sets Handled to true, so there's no need to use e.Handled= true;
void RTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
//do ...
bool temp = Multiline;
Multiline = true;
e.Handled = true;
Multiline = temp;
}
}

How to Stop Window Error Sound When Typing 'Enter' or 'Esc'

I have a form with a single text box on it. No other controls. Whenever I type the 'Enter' key or the 'Esc' key, the form functions as I desire; but I hear that horrible Windows error sound. The code looks similar to the following...
public class EntryForm: Form
{
public EntryForm()
{
}
private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
// do some stuff
Hide(); // I've also used DialogResult = DialogResult.OK here
e.Handled = true;
}
else if(e.KeyCode == Keys.Escape)
{
Hide(); // I've also used DialogResult = DialogResult.Cancel here
e.Handled = true;
}
}
}
I can 'hack' it and make the noise stop by adding the following code to the form's constructor.
AcceptButton = new Button();
CancelButton = new Button();
As I stated this causes the sound to not play, but I think this is bad form; especially since I don't need a button on the form.
Anyone know why this is the behavior and if there is a cleaner way to stop the error sound from playing?
In the KeyDown event, set e.Handled = true and e.SuppressKeyPress = true.
There's a more "correct" fix, one that works regardless of how many controls you have and follows the Windows Forms design model. Paste this code into your form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Escape || keyData == Keys.Enter) {
this.Hide();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
This is too long a reply to Nobugz answer to fit in a comment. If you use Nobugz code as is :
the Form is going to be hidden no matter which control on the form is active and has keyboard input focus, and that is independent of whether the Form has the 'KeyPreview property set to 'true or 'false.
Here's what you need to do to make only a specific control (in this case a TextBox named 'textBox1) be hidden in the ProcessCmdKeys over-ride :
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.HWnd == textBox1.Handle)
{
if (keyData == Keys.Escape || keyData == Keys.Enter)
{
textBox1.Hide();
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
Of course if you wanted to handle the case of multiple controls needing to be hidden, you could implement a 'switch statement or whatever to test the msg.HWnd against : note I make the assumption here that all controls that could have keyboard input will have a valid HWnd.
Some memory (vague) of a situation in which I used this technique, and a text input control somehow still had keyboard input focus ... when I did not intend for it to ... makes me want to add an additional test like this :
&& this.ActiveControl == textBox1
But, take that with a "grain of salt" since I can't be certain it is necessary.

Categories