【问题标题】:c# winform - how to delete multiple DataGridViewRowsc# winform - 如何删除多个DataGridViewRows
【发布时间】:2012-05-25 13:53:38
【问题描述】:

这是我的代码:

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 ?

【问题讨论】:

标签: c# winforms datagridview


【解决方案1】:

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

解决方案?请改用反向 for 循环。

【讨论】:

    【解决方案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

    【讨论】:

      【解决方案3】:

      当您使用 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&lt;T&gt; 或ICollection&lt;T&gt; 接口的集合。所以,是的,该过程可用于 Lists、Dictionaries、ControlCollections 和所有其他类似的类。

      【讨论】:

        【解决方案4】:

        对 column[0] 进行降序排序,然后从底部删除行。一旦 abc 结束,你也可以打破循环。 否则,您可以在您正在使用的数据表上放置一个行过滤器。

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

        【讨论】:

          【解决方案5】:

          每当我必须在 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);
          

          【讨论】:

            猜你喜欢
            • 2015-04-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-07
            • 1970-01-01
            • 1970-01-01
            • 2018-11-30
            • 1970-01-01
            相关资源
            最近更新 更多