簡體   English   中英

從DataGridView中刪除行時出現意外行為

[英]Unexpected behavior while deleting row from DataGridView

我使用下面的代碼刪除選定的行格式DataGridView但我有問題,這個代碼將始終刪除一半已檢查的行

就像我檢查了兩行中的兩行一樣,它會刪除一行並留下另一行

private void B_DeleteProduct_Click(object sender, EventArgs e)
{
    if (MessageBox.Show("selected row deleted", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    {
        foreach (DataGridViewRow RowToDelete in DGV_INVOICE.Rows)
        {
            object Cell = RowToDelete.Cells["Edit_Checkbox"].Value;

            if (Cell.ToString() == "True")
            {
                DGV_INVOICE.Rows.Remove(RowToDelete);
            }
        }
    }
}

您正在修改正在迭代的集合。 通常它會導致無效的操作異常,但在這種情況下不會。

DataGridViewRowCollection的內部實現允許您在foreach循環中修改集合,因此從技術上講, 您可以在foreach循環期間修改集合,並且不會收到異常。 但是如果你像在代碼中那樣執行它,那么只有一半的項目會被刪除。

這是因為在刪除索引0處的項目之后,項目索引將減少1,索引1處的前一項目將轉到索引0,依此類推,然后迭代器將索引1用於下一項目,而索引1處的上一項目為索引0現在。 這樣一個項目將被刪除,一個項目將被繞過,直到收集結束。

要解決此問題,您可以找到要刪除的項目並將其保留在列表中,然后在列表上進行迭代並將其從原始集合中刪除。 你可以使用linq Where找到行和ToList將它們存儲在提到的列表中然后刪除它們:

this.dataGridView1.Rows.Cast<DataGridViewRow>()
    .Where(row => (bool?)row.Cells[1].Value == true)
    .ToList().ForEach(x =>
    {
        this.dataGridView1.Rows.Remove(x);
    }); 

你也可以使用反向for循環 ,但我認為上面的方法更具可讀性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM