2
votes

This simple problem reoccurs many times for me in .NET with WinForms. I have a textbox and would like to treat the Enter key as the same as the Tab key, as in whenever I press enter, I want lostfocus to be raised, the next control to be Focused, etc. I have noticed many similar questions to this, and I can solve the problem by capturing the KeyDown and when Enter is detected to move the focus, but what I am looking for is a best practice and if not for insight on where the Textbox control detects the Tab key internally and how it does it's thing so I can just add an "|| key == Keys.Enter". This would stop Keydown from being raised and instead move focus to the next control and raise other appropriate messages.

I checked this similar question before .NET TextBox - Handling the Enter Key but it isn't what I really want to accomplish. What i really want to do is to as early as possible interpret ENTER as TAB in the Textbox control or intercept and change the Enter to a Tab and let the Textbox do it's thing.

Edit: Here's something along the lines of what I'm looking for, but I'm not sure the "safety" of modifying the Windows message like this...

class FancyTextBox : TextBox
{
    public bool TreatEnterAsTab { get; set; }
    const int WM_KEYDOWN = 0x100;
    const int KEY_TAB= 9;
    const int KEY_ENTER = 13;

    public override bool PreProcessMessage(ref Message msg)
    {
        if (TreatEnterAsTab && msg.Msg == WM_KEYDOWN && msg.WParam.ToInt32() == KEY_ENTER)
            msg.WParam = new IntPtr(KEY_TAB);

        return base.PreProcessMessage(ref msg);
    }
}
2

2 Answers

3
votes

This is fine. Just a few details, you don't want to do it if the text box is multiline or when the Shift, Alt or Ctrl key is down. Turn it on by default, that's why you're using it:

using System;
using System.ComponentModel;
using System.Windows.Forms;

class FancyTextBox : TextBox {
    public FancyTextBox() {
        TreatEnterAsTab = true;
    }
    [DefaultValue(true)]
    public bool TreatEnterAsTab { get; set; }

    public override bool PreProcessMessage(ref Message msg) {
        if (TreatEnterAsTab && (!this.Multiline || this.AcceptsReturn) && 
            Control.ModifierKeys == Keys.None && 
            msg.Msg == WM_KEYDOWN && (Keys)msg.WParam.ToInt32() == Keys.Enter) {
              msg.WParam = (IntPtr)Keys.Tab;
        }
        return base.PreProcessMessage(ref msg);
    }
    private const int WM_KEYDOWN = 0x100;
}
2
votes

This may be not what you are looking for, but what I have done in the past is to check for enter in the KeyPress event and use Control.SelectNextControl to use the existing tab sequencing