如何使Enter键在Winforms DataGridViewTextBoxCell
中表现得像在正常的Winforms TextBox
中一样(在文本中添加新行,而不是更改当前单元格)?
答案 0 :(得分:9)
好吧,我发现了如何解决这个问题。首先,创建一个名为CustomDataGridViewTextBoxEditingControl
的类,该类派生自DataGridViewTextBoxEditingControl
,并覆盖EditingControlWantsInputKey
,如下所示:
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);
}
}
这会阻止DataGridView
处理Enter键并更改当前单元格。但是,它不会使Enter键添加新行。 (似乎DataGridViewTextBoxEditingControl
已删除了Enter键的功能)。因此,我们需要覆盖OnKeyDown
并自己实现这些功能,如下所示:
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);
}
然后,创建一个名为CustomDataGridViewTextBoxCell
的类,该类派生自DataGridViewTextBoxCell
,并覆盖EditType
属性以返回CustomDataGridViewTextBoxEditingControl
的类型。
public class CustomDataGridViewTextBoxCell : DataGridViewTextBoxCell
{
public override Type EditType
{
get
{
return typeof(CustomDataGridViewTextBoxEditingControl);
}
}
}
执行此操作后,您可以将现有列上的CellTemplate
属性设置为CustomDataGridViewTextBoxCell
,也可以创建一个派生自DataGridViewColumn
且预设为CellTemplate
的类到CustomDataGridViewTextBoxCell
,你就会全力以赴!
答案 1 :(得分:5)
您可以通过将DataGridViewCellStyle.WrapMode属性设置为true来执行此操作。来自MSDN:
如果某个单元格的WrapMode为False 包含文本,单元格显示 文本在一行上,并显示 任何嵌入的换行符都是框 字符。如果WrapMode为True 包含文本的单元格,单元格 将换行符显示为行 打破,但也包装任何行 超过细胞的宽度。
您可以通过访问单元格上的Style属性或通过使用列的DefaultCellStyle访问列中的所有单元格来为特定单元格设置此项。
[更新] 要在DataGridView中有选择地禁用Enter键,请将Message Filter添加到包含DataGridView的Form中,如下所示:
private KeyMessageFilter m_filter = null;
private void Form1_Load(object sender, EventArgs e)
{
m_filter = new KeyMessageFilter(this);
Application.AddMessageFilter(m_filter);
}
这是消息过滤器类:
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;
}
}
现在,编辑文本时会禁用Enter键,您必须按Tab键才能移动到下一个单元格。 Shift + Enter仍然会为您正在编辑的文本添加换行符。
希望这有帮助。
答案 2 :(得分:0)
尽管@Zach Johnson已经回答了这个问题的主要部分,但他的代码对我不起作用。在花费了很长时间并阅读了不同的线程之后,我意识到您还必须设置一些属性才能完成该工作。这是完整的代码,因此您可以运行一个示例: 定义CustomDataGridViewTextBoxCell:
<packaging>pom</packaging>
然后定义类class CustomDataGridViewTextBoxCell: DataGridViewTextBoxCell
{
public override Type EditType => typeof(CustomDataGridViewTextBoxEditingControl);
}
CustomDataGridViewTextBoxEditingControl
然后定义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);
}
}
:
DataGridViewRolloverCell
之后,定义类public class DataGridViewRolloverCell : DataGridViewTextBoxCell
{
public override Type EditType => typeof(CustomDataGridViewTextBoxEditingControl);
}
:
DataGridViewCustomColumn
现在,如果您有一个名为public class DataGridViewCustomColumn : DataGridViewColumn
{
public DataGridViewCustomColumn()
{
this.CellTemplate = new CustomDataGridViewTextBoxCell();
}
}
的{{1}},则代码将如下所示:
DatagridViewControl
现在重要:
您仍然必须在dgv
中将属性DataGridViewCustomColumn col = new DataGridViewCustomColumn();
dgv.Columns.Add(col);
设置为DefaultCellStyle
。在设计器中或使用以下代码进行操作:
WrapText
也不要忘记将属性true
设置为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;
。
然后它将起作用。