C#检查datagridview复选框列检查值的有效方法

时间:2016-06-08 15:57:10

标签: c# .net winforms datagridview

我有一个datagridview和一个复选框列。如果用户检查几行然后按下按钮,我希望能够从勾选方框的每一行获得某个单元格值。

可能是这样的:

foreach (DataGridViewRow row in dataGridView1.Rows)
{
    if (Convert.ToBoolean(row.Cells[CheckBoxColumn1.Name].Value) == true)
    {
        //...
    }
}

问题是datagridview最多可能包含3000或4000行。我想看看是否有更快的方法来获取已检查的行,而不是遍历网格的所有行。

4 个答案:

答案 0 :(得分:2)

如果您不想迭代所有行,则使用已检查行的临时列表 然后在单击按钮后使用该列表中的值

HashSet<DataGridViewRow> _CheckedRows = new HashSet<DataGridViewRow>();

private void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (DataGridView.Columns[e.ColumnIndex].Name.Equals(CheckBoxColumn1.Name) == false)
        return;

    DataGridViewRow row = DataGridView.Rows[e.RowIndex];
    if (Convert.ToBoolean(row.Cells[CheckBoxColumn1.Name].Value) == true)
    {
        _CheckedRows.Add(row);
    }
    else
    {
        _CheckedRows.Remove(row);
    }
}

答案 1 :(得分:1)

您可以管理自己的已检查行列表。 您将绑定到dataGridView1.CellClick事件,并从列表中添加/删除行:

var checkedRows = new List<DataGridViewRow>();

dataGridView1.CellClick += (sender, args) =>
{
    if (args.RowIndex != YOUR_CHECKBOX_COLUMN_INDEX)
    {
        return;
    }

    var cell = dataGridView1[args.ColumnIndex, args.RowIndex];

    if (cell.Value == null)
    {
        cell.Value = false;
    }

    cell.Value = !(bool)cell.Value;

    if ((bool)cell.Value)
    {
        checkedRows.Add(dataGridView1.Rows[args.RowIndex]);
    }
    else
    {
        checkedRows.Remove(dataGridView1.Rows[args.RowIndex]);
    }
};

您需要做的就是:

foreach (DataGridViewRow row in checkedRows)
{
    //...
}

答案 2 :(得分:0)

您可以像这样使用Linq

var checkedRows = from DataGridViewRow r in dataGridView1.Rows
                  where Convert.ToBoolean(r.Cells[CheckBoxColumn1.Name].Value) == true
                  select r;

foreach (var row in checkedRows)
{
    //
}

答案 3 :(得分:0)

使用CheckBoxColumn1.Name代替CheckBoxColumn1.Index对我来说似乎是个小瓶颈。

为避免转换为DataGridViewRow和Boolean,我的建议是(未经测试):

int colIndex = CheckBoxColumn1.Index; // or dataGridView1.Columns.IndexOf(CheckBoxColumn1.Name) ?
for ( int r = 0; r < dataGridView1.RowCount; r++ )
{
    if ( true.Equals( dataGridView1[colIndex, r].Value ) )
    {
        //...
    }
}

使用单元格事件的其他答案更好,因为已检查的行列表将在需要时准备就绪,但根据您进行过滤和休息的方式,维护/调试也会更难。这是我的版本:

private HashSet<int> checkedRowIndexes = new HashSet<int>();

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if ( e.ColumnIndex == CheckBoxColumn1.Index ) 
    {
        if ( true.Equals( dataGridView1[CheckBoxColumn1.Index, e.RowIndex].Value ) )
            checkedRowIndexes.Add(e.RowIndex);
        else 
            checkedRowIndexes.Remove(e.RowIndex);
    }
}