我使用下面的代码删除选定的行格式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);
}
}
}
}
答案 0 :(得分:3)
您正在修改正在迭代的集合。通常它会导致无效的操作异常,但在这种情况下不会。
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);
});
你也可以使用反向循环,但我认为上面的方法更具可读性。