编辑后如何重新选中DataGridView(DGV)中的同一单元格?
DataGridView 更新后保持当前单元格选中的问题
抱歉,这可能是个基础问题,我刚开始学习C#和编程。DataGridView(DGV)的默认行为似乎是跳转到下一行的第0列。我尝试了如下代码,但这样只能重新选中下一行的同一单元格。我遗漏了什么?非常感谢!
private void DBUpdate() { da = new MySqlDataAdapter("SELECT * FROM WPVersand WHERE erledigt =''", Globals.cn); MySqlCommandBuilder cb = new MySqlCommandBuilder(da); cb.ConflictOption = ConflictOption.OverwriteChanges; System.Data.DataTable changes = dt.GetChanges(); if (changes != null) { if (dt.Rows.Count > 0) { // Set the current cell to the updated cell int row = dgvDaten.CurrentCell.RowIndex; int column = dgvDaten.CurrentCell.ColumnIndex; DialogResult res = MessageBox.Show("Änderung übernehmen?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (res == DialogResult.Yes) { da.Update(changes); dt.AcceptChanges(); dgvDaten.CurrentCell = dgvDaten[column, row]; dgvDaten.Refresh(); } else if (res == DialogResult.No) { bs = new BindingSource(); bs.DataSource = dt; dgvDaten.AutoGenerateColumns = true; dgvDaten.Columns.Clear(); dgvDaten.DataSource = bs; } } } } private void dgvDaten_CellValueChanged(object sender, DataGridViewCellEventArgs e) { bs.EndEdit(); dgvDaten.EndEdit(); DBUpdate(); }
问题原因与解决方法
核心问题:你在
CellValueChanged事件里调用DBUpdate时,DataGridView已经自动完成了焦点跳转的默认行为,此时记录的row和column是跳转后的单元格索引,不是你编辑的目标单元格。同时,CellValueChanged会在单元格内容刚修改就触发,时机过早,容易干扰焦点逻辑。修正步骤:
- 改用
CellEndEdit事件触发更新,这个事件在单元格编辑真正结束时触发,能准确获取到被编辑的单元格位置。 - 把被编辑的单元格索引作为参数传入
DBUpdate,更新完成后直接定位到该单元格。
- 改用
修正后的代码示例
更换事件处理方法
private void dgvDaten_CellEndEdit(object sender, DataGridViewCellEventArgs e) { // 记录真正被编辑的单元格位置 int editedRow = e.RowIndex; int editedCol = e.ColumnIndex; bs.EndEdit(); DBUpdate(editedRow, editedCol); }
修改DBUpdate方法
private void DBUpdate(int targetRow, int targetCol) { da = new MySqlDataAdapter("SELECT * FROM WPVersand WHERE erledigt =''", Globals.cn); MySqlCommandBuilder cb = new MySqlCommandBuilder(da); cb.ConflictOption = ConflictOption.OverwriteChanges; System.Data.DataTable changes = dt.GetChanges(); if (changes != null) { if (dt.Rows.Count > 0) { DialogResult res = MessageBox.Show("Änderung übernehmen?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (res == DialogResult.Yes) { da.Update(changes); dt.AcceptChanges(); // 校验单元格索引合法性,避免越界报错 if (targetRow >= 0 && targetRow < dgvDaten.Rows.Count && targetCol >=0 && targetCol < dgvDaten.Columns.Count) { dgvDaten.CurrentCell = dgvDaten[targetCol, targetRow]; // 可选:自动滚动到目标单元格位置 dgvDaten.FirstDisplayedScrollingRowIndex = targetRow; } } else if (res == DialogResult.No) { // 直接回滚修改,无需重新绑定数据源 dt.RejectChanges(); // 恢复焦点到编辑的单元格 if (targetRow >= 0 && targetRow < dgvDaten.Rows.Count && targetCol >=0 && targetCol < dgvDaten.Columns.Count) { dgvDaten.CurrentCell = dgvDaten[targetCol, targetRow]; } } } } }
额外说明
原代码中取消修改分支的重新绑定数据源操作过于冗余,调用dt.RejectChanges()即可直接回滚未提交的修改,无需重构BindingSource和清空列。
内容的提问来源于stack exchange,提问作者widarddd
相关产品推荐
相关产品推荐

