2009-10-22 46 views
4

这里是我的代码:如何使用foreach循环删除面板中的所有控件?

private void ClearSearchResults() 
    { 
     foreach (Control X in panel1.Controls) 
     { 
      panel1.Controls.Remove(X); 
     } 
    } 

问题是,当我运行这个方法,只有一个项目被删除,那么如果我再次点击一个按钮,以便该方法可以再次运行,另一个被删除。

如果我在我的面板中有10个控件,我必须多次单击我的程序上的“删除”按钮才能删除所有控件。

我能在这种情况下做什么?

+0

面板的类型是什么? – 2009-10-22 15:26:24

+0

面板的类型应该是不相关的,上面的代码可以在任何控件集合上运行。即表单本身或任何类型的容器(包括用户控件) – 2009-10-22 16:57:19

回答

14

这是否适合您?

private void ClearSearchResults() 
{ 
    panel1.Controls.Clear(); 
} 

编辑强调CKret的评论。

+0

是的,它的工作原理。真的很奇怪。为什么foreach声明不能做到这一点? – 2009-10-22 15:27:23

+0

+1击败我吧... – 2009-10-22 15:27:42

+0

@ Papuccino1,我的回答可能会解释这一点。 – 2009-10-22 15:28:03

8

我相信你在改变IEnumareble时,当你从它移除一个项目,而迭代它。

尝试使用简单的for循环而不是foreach。

+0

这是正确的解释。枚举时不能更改集合。 – 2009-10-22 15:30:32

+0

如果删除所有项目,则应使用常规循环并向后循环。否则,您将删除其他所有项目,然后获取OutOfBounds异常。 – 2009-10-22 15:35:20

+0

@CKret,是里德的例子说明了如何处理它。 – 2009-10-22 15:38:39

2

也许这:

panel1.Controls.Clear() 
1

由于我不知道你用的那种面板的,通常可以拨打panel1.Controls.Clear

16

你,在一般情况下,不能从一个集合在迭代中删除从它生成的枚举。而不是使用的foreach的,典型的方法是使用一个for循环向后工作:

private void ClearSearchResults() 
{ 
    for(int i=panel1.Controls.Count-1;i>=0;--i) { 
     panel1.Controls.RemoveAt(i);   
     // or 
     // Control X = panel1.Controls[i]; 
     // panel1.Controls.Remove(X); 
    } 
} 

然而,在这种情况下,只需使用clear:

panel1.Controls.Clear(); 
+0

+1这就是我所期待的,谢谢你比我更懒惰。 :) – 2009-10-22 15:29:32

+0

呵呵呵,我没有看到你的,当我开始,或者我可能不会打扰:) – 2009-10-22 15:32:00

3

因为一开始你不应该修改在foreach循环中的IEnumerable集合。您应该使用for循环或一段时间。

I.e.

private void ClearSearchResults() 
    { 
     while (panel1.Controls.Count > 0) 
     { 
      panel1.Controls.RemoveAt(0); 
     } 
    } 

或只使用:

panel1.Controls.Clear(); 
+0

这段代码不会工作,RemoveAt(0)?你需要一个索引器 – 2009-10-22 15:31:13

+0

它会工作。因为如果集合中至少有一个元素,那么在索引0处总是有一个元素。 – 2009-10-22 15:38:11

+0

@Stan R - 它是一个while循环,所以它不需要索引器 – GenericTypeTea 2009-10-22 15:40:55

0
private void ClearSearchResults() 
     { 
      foreach (Control X in panel1.Controls) 
      { 
       panel1.Controls.Remove(X); 
      } 
      if (panel1.Controls.Count > 0) 
      { 
       ClearSearchResults(); 
      } 
     } 
+0

这是不好的代码,看看其他的解释。 – 2009-10-22 15:32:14

+2

你在开玩笑吗? – 2009-10-22 15:32:20

+0

它的工作原理(我发布后看到明确的选项) – Crash893 2009-10-22 15:35:59

0

事实上,因为它打破了迭代器那么简单的解决办法是这样的,你不能使用Remove

var controls = in c from panel1.Controls select c; 
foreach(Controls _control in controls) 
{ 
    panel1.Controls.Remove(_control); 
} 

但当然,你不想坚持循环,然后继续使用panel1.Controls.Clear()

+0

当然,这不起作用,因为当你删除一个控件时,你改变了现有的控件索引。你也循环太多。假设有2个控件,你的循环表示从0开始,并在索引= 2结束。当你删除一个控件时,你实际上改变了所有当前控件的索引。解决方案是简单地循环控制的数量,但在索引0处移除。 int n; n = panel1.Controls.Count-1; (int i = 0; i <= n; i ++) 控制c = panel1.Controls [0]; panel1.Controls.Remove(c); } – JonH 2009-10-22 18:01:20

0
  int n; 
      n = panel1.Controls.Count-1; 

      for (int i = 0; i <= n; i++) 
      { 
       Control c = panel1.Controls[0]; 
       panel1.Controls.Remove(c); 
      } 
0
while (panel1.Controls.Count != 0) 
{ 
    foreach (Control c in panel1.Controls) 
    { 
     panel1.Controls.Remove(c); 
    } 
} 

另一种方式!