DataGridView: How can I make the enter key add a new line instead of changing the current cell?

Well, I found out how to solve the problem. First, create a class called CustomDataGridViewTextBoxEditingControl which derives from DataGridViewTextBoxEditingControl, and override EditingControlWantsInputKey like this:

public class CustomDataGridViewTextBoxEditingControl : DataGridViewTextBoxEditingControl
    {
        public override bool EditingControlWantsInputKey(
        Keys keyData, 
        bool dataGridViewWantsInputKey)
        {
            switch (keyData & Keys.KeyCode)
            {
                case Keys.Enter:
                    // Don't let the DataGridView handle the Enter key.
                    return true;
                default:
                    break;
            }

            return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey);
    }
}

This stops the DataGridView from handing the Enter key and changing the current cell. It does not, however, make the Enter key add a new line. (It appears that the DataGridViewTextBoxEditingControl has removed the functionality of the Enter key). Therefore, we need to override OnKeyDown and implement the functionality ourselves, like this:

protected override void OnKeyDown(KeyEventArgs e)
{
    switch (e.KeyCode & Keys.KeyCode)
    {
        case Keys.Enter:
            int oldSelectionStart = this.SelectionStart;
            string currentText = this.Text;

            this.Text = String.Format("{0}{1}{2}",
                currentText.Substring(0, this.SelectionStart),
                Environment.NewLine,
                currentText.Substring(this.SelectionStart + this.SelectionLength));

            this.SelectionStart = oldSelectionStart + Environment.NewLine.Length;
            break;
        default:
            break;
    }

    base.OnKeyDown(e);
}

Then, create a class called CustomDataGridViewTextBoxCell which derives from DataGridViewTextBoxCell, and override the EditType property to return the type of CustomDataGridViewTextBoxEditingControl.

public class CustomDataGridViewTextBoxCell : DataGridViewTextBoxCell
{
    public override Type EditType
    {
        get
        {
            return typeof(CustomDataGridViewTextBoxEditingControl);
        }
    }
}

After you do this, you can set the CellTemplate property on an existing column to a CustomDataGridViewTextBoxCell, or you can create a class derived from DataGridViewColumn with CellTemplate preset to a CustomDataGridViewTextBoxCell, and you will be all set!


You can do this by setting the DataGridViewCellStyle.WrapMode property to true. From MSDN:

If WrapMode is False for a cell that contains text, the cell displays the text on a single line, and displays any embedded newline characters as box characters. If WrapMode is True for a cell that contains text, the cell displays newline characters as line breaks, but also wraps any lines that exceed the width of the cell.

You can set this for specific cells by accessing the Style property on a cell, or for all cells in a column by using the DefaultCellStyle for the column.

[Update] To disable the Enter key selectively in your DataGridView, add a Message Filter to the Form containing the DataGridView as shown below:

private KeyMessageFilter m_filter = null;

private void Form1_Load(object sender, EventArgs e)
{
    m_filter = new KeyMessageFilter(this); 
    Application.AddMessageFilter(m_filter);

}

Here is the message filter class:

public class KeyMessageFilter : IMessageFilter
{
    private Form m_target = null;

    public KeyMessageFilter(Form targetForm)
    {
        m_target = targetForm;
    }

    private const int WM_KEYDOWN = 0x0100;

    private const int WM_KEYUP = 0x0101;


    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            //Note this ensures Enter is only filtered if in the 
            // DataGridViewTextBoxEditingControl and Shift is not also  pressed.
            if (m_target.ActiveControl != null && 
                m_target.ActiveControl is DataGridViewTextBoxEditingControl && 
                (Keys)m.WParam == Keys.Enter && 
                (Control.ModifierKeys & Keys.Shift) != Keys.Shift)
            {
                return true;
            }

        }

        return false;
    }
}

Now, the Enter key is disabled when editing text and you must press the tab key to move to the next cell. Shift + Enter still adds a newline to the text you are editing.

Hope this helps.