DataGridView: how can I make an input key, add a new row instead of changing the current cell?

How to make the Enter key behave in Winforms DataGridViewTextBoxCell , as in regular Winforms TextBox (add a new line to the text instead of the current cell)?

+8
winforms datagridview
source share
3 answers

Well, I found out how to solve the problem. First, create a class called CustomDataGridViewTextBoxEditingControl that inherits from DataGridViewTextBoxEditingControl , and override EditingControlWantsInputKey for example 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 passing the Enter key and changing the current cell. However, this does not force the Enter key to 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 this function ourselves, for example 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 that inherits from DataGridViewTextBoxCell , and override the EditType property to return the type CustomDataGridViewTextBoxEditingControl .

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

After that, you can set the CellTemplate property in the existing column to CustomDataGridViewTextBoxCell or create a class derived from DataGridViewColumn with the CellTemplate for CustomDataGridViewTextBoxCell , and you're done!

+9
source share

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 in one line and displays any inline newline characters as a window characters. If WrapMode is True for a cell containing 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 in a cell or all cells in a column using the DefaultCellStyle column for the column.

[Update] To selectively disable the Enter key 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 when editing text, the Enter key is disabled, and you must press the tab key to go to the next cell. Shift + Enter still adds a new line to the text you are editing.

Hope this helps.

+5
source share

Although @Zach Johnson answered the bulk of this question, its code did not work for me. After spending a long time and reading various topics, I realized that you also need to set some properties in order to get this working. So, here is the full code, so you can run the example: Define CustomDataGridViewTextBoxCell:

 class CustomDataGridViewTextBoxCell: DataGridViewTextBoxCell { public override Type EditType => typeof(CustomDataGridViewTextBoxEditingControl); } 

Then define the CustomDataGridViewTextBoxEditingControl class

 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); } 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 define the DataGridViewRolloverCell :

 public class DataGridViewRolloverCell : DataGridViewTextBoxCell { public override Type EditType => typeof(CustomDataGridViewTextBoxEditingControl); } 

After that, we define the DataGridViewCustomColumn class:

 public class DataGridViewCustomColumn : DataGridViewColumn { public DataGridViewCustomColumn() { this.CellTemplate = new CustomDataGridViewTextBoxCell(); } } 

Now, if you have a DatagridViewControl called dgv , your code will look like this:

 DataGridViewCustomColumn col = new DataGridViewCustomColumn(); dgv.Columns.Add(col); 

Now it’s important : you should still set the WrapText property to DefaultCellStyle to true . Do this in the constructor or with this code:

 DataGridViewCellStyle dataGridViewCellStyle1 = DataGridViewCellStyle(); dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText; dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; this.dgv.DefaultCellStyle = dataGridViewCellStyle1; 

And don't forget to set the Datagridview.AutoSizeRowsMode property in AllCells . Then it will work.

0
source share

All Articles