Trapping Enter key in Windows Forms TextBox

Suppose you want to do something special when the user hits enter in one of your Windows Forms app's TextBoxes? "Easy!", you say, thinking about hooking up a KeyDown event handler – until you try it and find out it doesn't actually work. And then you go Googling, just like I did earlier today.

And yeah, it's true, you can't catch keys reserved for form navigation with KeyDown or KeyPress events. Well, that blows. Of course, a quick search of the web turns up quite a few workarounds, so you're saved. Since I figured this out already, let me save you some time.

When a key is hit in a TextBox control, a method named IsInputKey gets called on the control. That method takes a Keys enumeration as a parameter and returns a bool – true if that particular key is an "input key", false if not. False also means that the form handler will take care of (or ignore) the keystrike instead of passing it over to the control. And you guessed it, TextBox.IsInputKey returns false for Keys.Enter (this is different if you have a multiline textbox and AcceptReturn enabled, but let's not go there now).

So, your problem is solved once you make your TextBoxes accept enter as an input key. The answer is subclassing the textbox, i.e. creating your own control. That's not really as bad as it sounds. In fact, you can get away with just this:

public class EnterTextBox : TextBox {
protected override bool IsInputKey(Keys key) {
if (key == Keys.Enter)
return true;
return base.IsInputKey(key);
}
}

Now start using your new textbox controls. If you're using no IDE at all or you have Visual Studio, just go and substitute new EnterTextBox() for new System.Windows.Forms.TextBox(). VS's Form Designer seems to handle this quite nicely. If you're using #develop, you can't use that shortcut – #develop forms designer will wipe away your textboxes. Luckily your EnterTextBox will have appeared in the Custom Components section of the toolbox, so it's only a matter of dragging some controls.

As you can guess, the following event handler now works properly:

void TextBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Enter) {
e.Handled = true;
MessageBox.Show("Enter hit in textbox1!");
}
}

Remember to set Handled to true to signal the textbox that the keystroke has actually been dealt with already.

If you did the Googling part, you probably saw there are a few other solutions to this as well. One of them involves overriding ProcessDialogKey, and another common one is overriding the WndProc handler. They both get notifications for enter hits regardless of what IsInputKeys returns. If you have a static definition for what enter should mean (for example, always clear the field), you could use one of those approaches. However, if the action required varies by field, you should use the solution above to override IsInputKey instead – that way you can hook into the KeyDown event to customize behavior on an instance-by-instance basis.

Be Sociable, Share!

August 19, 2004 · Jouni Heikniemi · 14 Comments
Posted in: .NET

14 Responses

  1. Lex Alexander - August 5, 2005

    Hi,
    first, thanks for the article, helped me a lot.
    When I first tried to use your solution, I ran into some problems – althought I made everything as you did, with the difference that I was not using a TextBox but a ToolStripTextBox.
    I modified your code to override the ToolStripTextBox – but did have no success the overridden Method was never called.
    When I replaced the ToolStripTextBox with a regular TextBox everything worked fine.

  2. Richard - December 19, 2005

    Thanks!

  3. Cliff - January 25, 2006

    I have this implemented for the tab & shift-tab key. Everything works as I want, but every time the tab or shift-tab key is pressed a beep sound is generated! Does anyone know why ? and how to prevent it from happening.
    Not sure if this matters but my inherited textbox control resides on a usercontrol (and not a dialog or form)
    Thanks.

  4. Brian - February 28, 2006

    You can also try this:
    private void txtMyTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
    //if the user presses the Enter key, do some action
    int ascii = (int)e.KeyChar;
    if (ascii == 13)
    {
    e.Handled = true;
    this.Something();
    }
    }

  5. Pieter - March 14, 2006

    I like your solution Brian.
    Saved me a lot of work with this trick.
    Thx :)

  6. Eric - May 26, 2006

    Thank you. This was very helpful.
    I did note one thing that may help others.
    I originally encountered this problem on a form with the AcceptButton property set to an "OK" button.
    When I reset the AcceptButton property to "(none)", I was able to intercept the ENTER button without overriding the IsInputKey method.
    For me this, was an easier change. I simply communicate the DialogResult differently.
    -Eric.

  7. brief thanks - August 21, 2006

    you sir are a legend. congratulations upon receiving such an accolade.
    saved me a good spot of google trawling ™
    cheers buddy
    ;)

  8. xtian - December 18, 2006

    Hmm – just tried this in .NET 2.0, and it seems that KeyPress is fired when an Enter is sent to a vanilla textbox. Is this something that's likely to have been fixed in the new version?

  9. xtian - December 18, 2006

    Oops – changed the form so that the AcceptButton was set, and saw exactly the behaviour you describe. Thanks!

  10. Yuri - March 26, 2007

    e.Handled = True. Too right.
    Thanks a lot! IsInputKey's been driving me nuts.

  11. Allan K - March 28, 2007

    Nice, just that I needed.
    Alllan
    /Denmark

  12. Dameure - April 10, 2008

    Thanks a lot. Great solution :-)

  13. ALexanderT - October 2, 2009

    just put this in an keydown or up event:

    if (e.KeyData == Keys.Enter)
    {
    //do action
    }

    easy, clean and quick

  14. Róbert Badí Baldursson - December 10, 2009

    Hi

    This didn't work as expected for me originally untill I changed the event from KeyDown to KeyPress and then the event handler looks like this:

    private void _example_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
    if (e.KeyChar == Convert.ToChar(13))
    {
    e.Handled = true;
    _btn_Click(this, e);
    }
    }

Leave a Reply