c#winform - 如何删除多个DataGridViewRows

时间:2012-05-25 04:16:21

标签: c# winforms datagridview

这是我的代码:

foreach (DataGridViewRow r in dgv01.Rows)

if (r.Cells[0].Value.ToString() == abc)

{

dgv01.Rows.Remove(r);

//dgv01.CurrentCell = dgv01.Rows[0].Cells[0]; - **also tried**

}

但只删除了一些行 - 并非全部指定!?

为什么 - foreach - 并不代表 - foreach

5 个答案:

答案 0 :(得分:4)

我必须提醒您,当您想要修改/删除正在遍历的数据时,使用foreach块是危险的。删除会与foreach迭代器的索引混淆。

解决方案?改为使用反向循环。

答案 1 :(得分:2)

首先,在foreach循环中更改集合并不是一个好主意。其次foreach不按你想要的方式运行,因为一旦第一行被删除,第二行将成为第一行,但因为在foreach中,检查将在第二行完成,实际上是第三行。因此,已跳过检查第二行。最好的方法是以相反的顺序使用for循环。

要知道为什么 foreach不像foreach那样行事尝试这个简单的例子。

 private List<int> list = Enumerable.Range(0, 10).ToList<int>();
 for(int i=0;i<list.Count;++i)
       {
           if (list[i] < 5)
               list.RemoveAt(i);
       }

       list.ForEach(x => Console.Write(x));

<强>输出:
    1356789

答案 2 :(得分:2)

使用foreach迭代集合时,不应修改集合,否则,在最佳情况下,最终不会覆盖整个集合。但是,大多数情况下,在foreach块内修改集合时,迭代将失败。

为了从DataGridView中删除行,您必须使用for迭代块或两步过程,我将在下面显示这两个过程。


for迭代块

此过程使用索引遍历集合,随时修改集合。你需要知道的是,如果你打算修改集合,你就没有索引增量(在集合中前进);你递减索引(向后通过集合)。如果您在向前迭代时修改(删除或添加项目)集合,则可能不会访问集合中的所有项目。

以下是从DataGridView中删除行的代码。请记住,我们迭代向后

for (int i = dgv01.Rows.Count - 1; i >= 0; i--)
{
    if (dgv01.Rows[i].Cells[0].Value.ToString() == "abc")
    {
        dgv01.Rows.RemoveAt(i);
    }
}


foreach迭代块

此过程使用两步法。第一步找到要删除的项目,第二步从集合中删除项目。由于我之前解释的原因,这个两步过程是必要的。

现在的代码。请记住,这是一个两步过程。

// step 1. find the items to be removed

//items to be removed will be added to this list
var itemsToRemove = new List<DataGridViewRow>(); 
foreach (DataGridViewRow r in dgv01.Rows)
{
    if (r.Cells[0].Value.ToString() == "abc")
    {
        itemsToRemove.Add(r);
    }
}


//step 2. remove the items from the DataGridView
foreach (var r in itemsToRemove)
{
    // this works because we're not iterating over the DataGridView.
    dgv01.Rows.Remove(r);
}


你应该知道的最后一件事是我在这里演示的程序不仅适用于DataGridViewRowCollection类;它适用于实现IList<T>ICollection<T>接口的所有集合。所以,是的,这个过程可以用于Lists,Dictionaries,ControlCollections和所有其他类似的类。

答案 3 :(得分:1)

对列[0]进行降序排序,然后从底部开始删除行。一旦abc结束,你也可以打破循环。 其他明智的你可以在你使用的dataTable上放置一个行过滤器。

((DataTable)this.datagrid1.DataSource).DefaultView .RowFilter

答案 4 :(得分:1)

每当我必须在foreach中修改一个集合时,我通常会创建一个新的集合,用我想要修改的数据填充,然后遍历第二个集合来对主集合进行实际更改。这样我就不会在循环时修改集合,所以我避免了MChicago所描述的情况。

在你的情况下,我通常会写这种代码:

List<DataGridViewRow> toDel = new List<DataGridViewRow>();
foreach (DataGridViewRow r in dgv01.Rows)    
    if (r.Cells[0].Value.ToString() == "abc")    
        toDel.Add(r);

foreach (DataGridViewRow aRow in toDel)   
    dgv01.Rows.Remove(aRow);