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

如何获取DataGridView中选中复选框对应行数据并存入数组?

解决DataGridView CheckBox列选中行数据收集的问题

我来帮你分析两段代码的问题,再给出靠谱的解决方案。

第一段代码的问题

先看你这段代码:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { 
    foreach (DataGridViewRow row in this.dataGridView1.Rows) { 
        if (Convert.ToBoolean(this.dataGridView1.Rows[e.RowIndex].Cells["chkBoxColumn"].Value = true) == true) { 
            MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString()); 
        } 
    } 
}

这里有两个关键错误:

  1. 循环没用到当前遍历的row:你在循环里一直操作e.RowIndex对应的行(也就是触发事件的那一行),所以循环多少次就会弹多少次这一行的内容,自然会重复弹出最后选中项。
  2. 赋值操作代替了判断:Value = true是把CheckBox的值强制设为true,而不是判断它是否为true,这会导致所有点击都会把当前CheckBox设为选中,逻辑完全错了。

第二段代码的问题

再看这段:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { 
    for (int i = 0; i < dataGridView1.Rows.Count; i++) { 
        if (bool.Parse(dataGridView1.Rows[i].Cells["chkBoxColumn"].Value.ToString()) == true) { 
            MessageBox.Show(dataGridView1.Rows[i].Cells[1].Value.ToString()); 
        } 
    } 
}

空引用异常的原因很明确:

  • DataGridView默认会在最后一行显示一个新行(IsNewRow为true),这一行的CheckBox值是null,调用Value.ToString()直接就会抛出空引用。
  • 就算不是新行,当CheckBox没被点击过的时候,Value也可能是null,bool.Parse同样会报错。

正确的实现方式

我们需要安全判断CheckBox状态,同时收集选中行到数组里,代码如下:

1. 核心事件代码

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
    // 只处理CheckBox列的变化,避免其他列触发无效操作
    if (e.ColumnIndex == dataGridView1.Columns["chkBoxColumn"].Index && e.RowIndex >= 0) {
        // 用List临时存储选中行,最后转成数组
        List<DataGridViewRow> selectedRowsList = new List<DataGridViewRow>();

        foreach (DataGridViewRow row in dataGridView1.Rows) {
            // 跳过新行,避免空引用
            if (row.IsNewRow) continue;

            // 安全判断CheckBox的值:先检查Value是否为null,再转换
            bool isChecked = false;
            if (row.Cells["chkBoxColumn"].Value != null) {
                isChecked = Convert.ToBoolean(row.Cells["chkBoxColumn"].Value);
            }

            if (isChecked) {
                selectedRowsList.Add(row);
            }
        }

        // 转换为数组,这就是你需要的选中行数组
        DataGridViewRow[] selectedRowsArray = selectedRowsList.ToArray();

        // 测试输出:遍历数组显示每行第2列内容(处理空值避免报错)
        foreach (var row in selectedRowsArray) {
            string cellValue = row.Cells[1].Value?.ToString() ?? "该单元格为空";
            MessageBox.Show(cellValue);
        }
    }
}

2. 额外优化:解决CheckBox点击不立即触发事件的问题

默认情况下,DataGridView的CheckBox需要点击两次才会触发CellValueChanged,我们可以加一个事件来修复这个问题:

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
    if (dataGridView1.IsCurrentCellDirty && dataGridView1.CurrentCell is DataGridViewCheckBoxCell) {
        // 立即提交单元格编辑状态
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

记得在窗体设计器里把这个事件绑定到DataGridView上,或者在构造函数里手动绑定:

public YourForm() {
    InitializeComponent();
    dataGridView1.CurrentCellDirtyStateChanged += dataGridView1_CurrentCellDirtyStateChanged;
}

这样修改后,就能完美解决你遇到的重复弹窗和空引用问题,正确收集所有选中行到数组中了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:51:08