2016-06-08 70 views
0

我有一个datagridview和一个复选框列连接到它。如果用户检查几行然后按下一个按钮,我希望能够从盒子被勾选的每一行中获得特定的单元格值。C#有效的方法来检查datagridview复选框列的检查值

的东西,也许是这样的:

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

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

+0

为什么你让你的用户筛选4000行? – LarsTech

+0

3000或4000行并不多。你有没有一个实际的性能问题? – Paparazzi

+0

@LarsTech这是用户的愿望。他们也将能够通过这个过滤。 – Iason

回答

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

酷!我迟到了第二个类似的答案。 –

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) 
{ 
    // 
} 
+4

更清晰的语法,但我怀疑它是更快 – Paparazzi

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) 
{ 
    //... 
} 
0

使用CheckBoxColumn1.Name代替CheckBoxColumn1.Index然后按钮被点击后,利用价值似乎是一个小小的瓶颈给我。

为了避免铸件的DataGridViewRow和布尔,我的建议是一样的东西(未测试):

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

@Fabio为我编译https://msdn.microsoft.com/en-us/library/0syx5449。如果需要的话可以选择'cell.Value.Equals(true)'或'object.Equals(cell.Value,true)' – Slai