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.