Click here to Skip to main content
Click here to Skip to main content

Redirect the Enter key from a Windows Forms TextBox

By , 24 Feb 2006
 

Sample Image - CustomizedTextBox.png

Introduction

Would you like to prevent the Enter key in a TextBox from automatically pressing the OK button of a Form, assuming you attached a OK button to the AcceptButton property of the Form?

The common way to redirect keys is to intercept their interpretation by attaching a method to the event handlers KeyPress or KeyDown of the TextBox control, or to derive from the class TextBox in order to override the methods OnKeyPress or OnKeyDown. Unfortunately, in this case, it fails: the redirection code is not interpreted and the OK button is automatically activated by the form itself. It happens because the parent form intercepts and stops the KeyPress and KeyDown signals. You don't get better results by overriding ProcessKeyPreview.

Instead, you have to inherit from TextBox and override the ProcessCmdKey virtual method.

The following C++ and C# code snippets show how to apply a tabulation when the user presses Enter, so that it switches to the next control.

Using the code

If you would like to use this code in your program, simply paste the class declaration in your code, and use CustomizedTextBox instead of System.Windows.Forms.TextBox in your code. If you want to enable the use of this control in the Forms Editor, then you should make a separate library project and import the contents of the DLL into the Visual Studio ToolBox.

The code in C#:

//! Use instances of this class instead of TextBox
// in order to Redirect the process of the Enter Key,
// before the Form does it for you
public class CustomizedTextBox : System.Windows.Forms.TextBox 
{    
    // This method intercepts the Enter Key
    // signal before the containing Form does
    protected override bool ProcessCmdKey(ref 
              System.Windows.Forms.Message m, 
              System.Windows.Forms.Keys k) 
    {
        // detect the pushing (Msg) of Enter Key (k)
        if(m.Msg == 256 && k == 
               System.Windows.Forms.Keys.Enter) 
        {
            // Execute an alternative action: here we
            // tabulate in order to focus
            // on the next control in the formular
            System.Windows.Forms.SendKeys.Send("\t");
            // return true to stop any further
            // interpretation of this key action
            return true; 
        }
        // if not pushing Enter Key,
        // then process the signal as usual
        return base.ProcessCmdKey(ref m,k);
    }
}

The code in managed C++:

 //! Use instances of this class instead
// of TextBox in order to Redirect the process
// of the Enter Key, before the Form does it for you
public __gc class CustomizedTextBox : 
       public System::Windows::Forms::TextBox 
{
protected:
    // This method intercepts the Enter Key
    // signal before the containing Form does
    virtual bool ProcessCmdKey(System::Windows::Forms::Message 
                           * m, System::Windows::Forms::Keys k) 
    {
        // detect the pushing (Msg) of Enter Key (k)
        if(m->Msg == 256 && k == 
               System::Windows::Forms::Keys::Enter) 
        {
            // Execute an alternative action: here we
            // tabulate in order to focus
            // on the next control in the formular
            System::Windows::Forms::SendKeys::Send(S"\t");
            // return true to stop any further
            // interpretation of this key action
            return true; 
        }
        // if not pushing Enter Key,
        // then process the signal as usual
        return __super::ProcessCmdKey(m,k);
    }
};

Points of Interest

I hope this code will prevent some of you from wasting 3 or 4 hours looking for a trick that is not really (conceptually) interesting, but useful.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jerome RG
Web Developer
Germany Germany
Member
Jerome RG studied Computer Science in France and Germany. He obtained a Master Degree in Computer Science of the Technical University of Berlin. In September 2005, he built with two colleagues a company developing IT Solutions for aeronautics.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Suggestionversion with EnterKeyPressed event handlermemberDan Randolph26 Aug '12 - 12:02 
Here is a tip that will make this custom control more useful.
By adding two lines of code and changing one, you can allow any event handler to be attached for the EnterKeyPressed event.
 
  public delegate void EnterKeyPressHandler(object sender);
 
  public partial class TextBoxCmb : System.Windows.Forms.TextBox
  {
    public TextBoxCmb()
    {
      InitializeComponent();
    }
    
    public event EnterKeyPressHandler EnterKeyPressed;
 
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
      if (msg.Msg == 256 && keyData == Keys.Enter)
      {
        EnterKeyPressed(this);
        return true;
      }
      return base.ProcessCmdKey(ref msg, keyData);
    }
  }
 
Now in VS Designer, when you add this control, you can create the usual designer auto-generated template method for the custom "EnterKeyPressed" event.
GeneralMy vote of 5memberDan Randolph26 Aug '12 - 11:11 
Just what I needed
GeneralMy vote of 5membermanoj kumar choubey12 Mar '12 - 21:51 
Nice
Questionenter keymemberdebasish_don7 Jan '12 - 4:54 
just after the namespaces i write all given coding for navigating to textboxex by usin enter key instead of tab key.but it compiled with no error,bt not functioning
GeneralYet another methodmemberxMotherx3 May '08 - 9:08 
What I've found is easiest is to add a button to the dialog that does your work and when the edit box is updated (the user clicks in it or adds a character), make this button the default button on your dialog so when they hit ENTER it presses this button FOR them automatically. You can hide the actual button so the user can't see it, if you like.
 
Let's say we have button "IDC_SEND_CMD_BTN" and I've added a CONTROL named m_SendCMD_BTN that's tied to this button via the dialog editor.
 
And I have an Editbox on my dialog and I've added a CONTROL named m_MainEdit_CTRL that's tied to this Editbox via the dialog editor.
 
Set Visible to FALSE in the dialog editor for your button if you don't want the user to see it.
 
Double click this button in the dialog editor to add your OnBtnClicked..().
 
Put the code in here to do whatever your intent it such as:
void CMFCApplicationDlg::OnBnClickedSendCmdBtn()
{
CString UserCommand;
m_MainEdit_CTRL.GetWindowTextA(UserCommand);
 
if( UserCommand.GetLength() )
{
//do stuff
}
 
m_MainEdit_CTRL.SetWindowText("");
}
 
Then override either OnEdit or OnChange (double click the edit control) for your CEdit control to look like this:
void CMFCApplication1Dlg::OnEnChangeMainEditCtrl()
{
m_SendCMD_BTN.SetButtonStyle(BS_DEFPUSHBUTTON,TRUE);
SetDefID(IDC_SEND_CMD_BTN);
}
 
so now when a user edits the Editbox, the default button is changed to my invisible button that will perform my work for me when they hit ENTER. The nice thing about this is that it allows you to quickly write the code using a button (which is easiest) and change it to work without needing a users explicit button press when you want to. Not to mention it's pretty simple. Wink | ;)
General[Message Deleted]memberalexreg25 Dec '06 - 1:14 

GeneralRe: Easiest MethodmemberMarkDoubson5 Nov '08 - 12:56 
This is not a same action - if multilined textbox used AcceptReturn - press Enter key will produce extra line instead of needed Tab action
GeneralAlternative methodmemberSidonath23 Mar '06 - 6:39 
I needed to redirect Enter key on only one ComboBox, so I tried to come up with another solution. Solution which wouldn't require me to create new controls for one specific task. Eventually I did.
 
What I did was to dereference AcceptButton in PreviewKeyDown event (this.AcceptButton = null;), and then reassign it in KeyDown event (this.AcceptButton = btnOk;).
 
It is pretty silly, but hey, it works Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 24 Feb 2006
Article Copyright 2006 by Jerome RG
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid