2016-06-08 120 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