繁体   English   中英

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

[英]C# Efficient way to check datagridview checkbox column for checked values

我有一个datagridview和一个复选框列附加到它。 如果用户检查了几行,然后按了一个按钮,我希望能够从勾选框的每一行中获取某个单元格值。

可能是这样的:

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

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

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

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);
    }
}

您可以管理自己的检查行列表。 您将绑定到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)
{
    //...
}

您可以这样使用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)
{
    //
}

对我来说,使用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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM