C# DataGridView使用CellEndEdit后焦点异常问题求助
修复DataGridView编辑模式下Enter键跳转异常问题
问题背景
需求如下:
- Enter键实现Tab键功能,跳转至下一单元格
- Back键返回上一单元格
- 焦点处于最后一行最后一列时自动新增一行
现有实现中,为解决编辑模式下KeyDown事件不触发的问题,添加了CellEndEdit事件并调用SendKeys.Send("{right}"),但出现异常:焦点先按DataGridView默认行为下移至下一行,再跳至该行下一单元格,不符合"跳转至当前行下一单元格"的预期。
问题根源
编辑模式下按Enter时,DataGridView默认会触发下移至下一行的行为,随后CellEndEdit事件里的SendKeys.Send("{right}")又触发右移操作,导致两次跳转叠加,出现异常效果。
修复方案
1. 拦截编辑控件的Enter键事件
通过EditingControlShowing事件获取单元格的编辑控件(如TextBox),在其KeyDown事件中直接处理Enter键逻辑,阻止默认下移行为,同时完成编辑和跳转。
2. 移除CellEndEdit中的SendKeys代码
避免重复触发跳转逻辑,消除冲突。
修改后的完整代码
1. 添加EditingControlShowing及编辑控件的KeyDown事件处理
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { var textBox = e.Control as TextBox; if (textBox != null) { // 先移除旧绑定,防止重复触发 textBox.KeyDown -= TextBox_KeyDown; textBox.KeyDown += TextBox_KeyDown; } } private void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { // 结束当前单元格编辑状态 dataGridView1.EndEdit(); // 复用原KeyDown事件中的跳转逻辑,保证行为一致 int currentCol = dataGridView1.CurrentCell.ColumnIndex; int currentRow = dataGridView1.CurrentCell.RowIndex; if (currentCol == dataGridView1.ColumnCount - 1) { if (dataGridView1.RowCount > currentRow + 1) { dataGridView1.CurrentCell = dataGridView1[0, currentRow + 1]; } else { dataGridView1.Rows.Add(); dataGridView1.CurrentCell = dataGridView1[0, currentRow + 1]; } } else { dataGridView1.CurrentCell = dataGridView1[currentCol + 1, currentRow]; } // 阻止DataGridView默认的Enter下移行为 e.SuppressKeyPress = true; e.Handled = true; } }
2. 修改CellEndEdit事件(移除SendKeys代码)
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { // 移除原有的SendKeys.Send("{right}"); 代码 }
3. 保留原KeyDown事件逻辑(非编辑模式下的按键处理)
原dataGridView1_KeyDown事件代码无需修改,继续处理非编辑模式下的Enter、Back、方向键等操作。
效果说明
- 编辑模式下按Enter:直接结束编辑,跳转至当前行下一单元格;若为当前行最后一列,则跳转至下一行第一列(无下一行时自动新增),无默认下移行为。
- 非编辑模式下的按键逻辑保持原有功能不变。
内容的提问来源于stack exchange,提问作者Ankit Goel
相关产品推荐
相关产品推荐

