You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编辑后如何重新选中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会在单元格内容刚修改就触发,时机过早,容易干扰焦点逻辑。

  • 修正步骤:

    1. 改用CellEndEdit事件触发更新,这个事件在单元格编辑真正结束时触发,能准确获取到被编辑的单元格位置。
    2. 把被编辑的单元格索引作为参数传入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:25:29