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

如何在C#中将选中行转移至另一DataGridView后删除原选中行?

解决方法:转移选中行后删除原列表中的对应行

你的现有代码已经实现了把dgAvailable中选中的行转移到dgSelected,但直接在遍历过程中删除行会触发集合修改异常(因为foreach遍历的集合不能在遍历中被修改)。正确的做法是先收集所有需要删除的行,再统一删除,具体修改如下:

修改后的完整代码(收集待删除行版)

private void BtnRight_Click(object sender, EventArgs e)
{
    // 先创建一个列表存储需要删除的行
    List<DataGridViewRow> rowsToDelete = new List<DataGridViewRow>();

    foreach(DataGridViewRow item in dgAvailabe.Rows)
    {
        // 跳过新行(如果允许用户添加行的话)
        if (item.IsNewRow) continue;

        DataGridViewCheckBoxCell chkchecking = item.Cells[0] as DataGridViewCheckBoxCell;
        if (Convert.ToBoolean(chkchecking.Value) == true)
        {
            // 转移行到dgSelected
            int n = dgSelected.Rows.Add();
            dgSelected.Rows[n].Cells[0].Value = item.Cells[1].Value.ToString();
            dgSelected.Rows[n].Cells[1].Value = item.Cells[2].Value.ToString();
            dgSelected.Rows[n].Cells[2].Value = item.Cells[3].Value.ToString();
            dgSelected.Rows[n].Cells[3].Value = item.Cells[4].Value.ToString();
            dgSelected.Rows[n].Cells[4].Value = item.Cells[5].Value.ToString();

            // 将当前行加入待删除列表
            rowsToDelete.Add(item);
        }
    }

    // 统一删除选中的行
    foreach (DataGridViewRow row in rowsToDelete)
    {
        dgAvailabe.Rows.Remove(row);
    }
}

关键说明

  • 收集待删除行:用List<DataGridViewRow>存储所有需要删除的行,避免在foreach遍历dgAvailabe.Rows时直接修改集合,防止抛出InvalidOperationException。
  • 跳过新行:如果你的dgAvailable开启了AllowUserToAddRows(默认是开启的),需要判断item.IsNewRow跳过最后一行的空行,避免误处理。
  • 统一删除:遍历待删除列表,调用Rows.Remove(row)删除对应行,这一步不会影响原集合的遍历安全。

备选方案:倒序for循环直接删除

如果你想减少中间集合的内存占用,也可以用倒序for循环直接遍历删除(倒序遍历不会因为前面的行被删除而导致索引偏移),代码示例如下:

private void BtnRight_Click(object sender, EventArgs e)
{
    // 倒序遍历dgAvailabe的行
    for (int i = dgAvailabe.Rows.Count - 1; i >= 0; i--)
    {
        DataGridViewRow item = dgAvailabe.Rows[i];
        if (item.IsNewRow) continue;

        DataGridViewCheckBoxCell chkchecking = item.Cells[0] as DataGridViewCheckBoxCell;
        if (Convert.ToBoolean(chkchecking.Value) == true)
        {
            // 转移行到dgSelected
            int n = dgSelected.Rows.Add();
            dgSelected.Rows[n].Cells[0].Value = item.Cells[1].Value.ToString();
            dgSelected.Rows[n].Cells[1].Value = item.Cells[2].Value.ToString();
            dgSelected.Rows[n].Cells[2].Value = item.Cells[3].Value.ToString();
            dgSelected.Rows[n].Cells[3].Value = item.Cells[4].Value.ToString();
            dgSelected.Rows[n].Cells[4].Value = item.Cells[5].Value.ToString();

            // 直接删除当前行,倒序遍历不会有索引问题
            dgAvailabe.Rows.RemoveAt(i);
        }
    }
}

两种方法都可以解决问题,第一种更直观易读,第二种内存占用略低,根据你的场景选择即可。

内容的提问来源于stack exchange,提问作者Godofsleepy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:19:46