2009-10-22 6 views
4

Voici le code que j'ai:Comment puis-je utiliser une boucle foreach pour supprimer tout le contrôle d'un panneau?

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

Le problème est, quand je lance cette méthode, un seul élément est supprimé, si je clique sur un bouton à nouveau si la méthode peut fonctionner à nouveau, un autre est supprimé .

Si j'ai 10 contrôle dans mon panneau, je devrais cliquer sur le bouton "Supprimer" sur mon programme de nombreuses fois pour tous les contrôles à supprimer.

Que puis-je faire dans ce cas?

+0

quel est le type de panneau? –

+0

le type de panneau ne devrait pas être pertinent, le code ci-dessus pourrait être exécuté sur n'importe quelle collection de contrôles. c'est-à-dire le formulaire lui-même ou tout type de conteneur (y compris les commandes de l'utilisateur) –

Répondre

14

Est-ce que cela fonctionne pour vous?

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

Modifié pour souligner le commentaire CKret.

+0

Oui, cela fonctionne. Vraiment bizarre. Pourquoi la déclaration foreach ne fait-elle pas l'affaire? –

+0

+1 me battre ... –

+0

@ Papuccino1, ma réponse pourrait expliquer cela. –

8

Je crois que vous modifiez le IEnumareble lorsque vous supprimez un élément de celui-ci lors de l'itérer. Essayez d'utiliser une simple boucle for à la place d'une foreach.

+0

Ceci est l'explication correcte. Vous ne pouvez pas modifier une collection en l'énumérant. –

+0

Si vous supprimez tous les éléments, vous devez utiliser une boucle normale et une boucle vers l'arrière. Sinon, vous supprimerez tous les autres éléments et obtiendrez une exception OutOfBounds. –

+0

@CKret, oui L'exemple de Reed illustre comment y faire face. –

2

Peut-être ceci:

panel1.Controls.Clear() 
1

Comme je ne sais pas le genre de panneau que vous utilisez, vous pouvez généralement appeler panel1.Controls.Clear

16

Vous, en général, ne peut pas retirer d'une collection tout en réitérant un énumérable généré à partir de celui-ci. Au lieu d'utiliser foreach, l'approche classique consiste à utiliser une boucle de travail en arrière:

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); 
    } 
} 

Cependant, dans ce cas, il suffit d'utiliser clair:

panel1.Controls.Clear(); 
+0

+1 c'est ce que je voulais savoir, merci d'être moins paresseux que moi Reed. :) –

+0

Hehehe, je ne voyais pas le vôtre quand j'ai commencé, ou je ne reviendrais probablement pas pris la peine :) –

3

Pour commencer, vous ne devez pas modifier la IEnumerable collection dans une boucle foreach. Vous devriez utiliser une boucle for ou un moment.

I.e.

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

ou tout simplement utiliser:

panel1.Controls.Clear(); 
+0

ce code ne fonctionne pas, RemoveAt (0)? vous avez besoin d'un indexeur –

+0

Cela fonctionnera. Car s'il y a atleast élément un dans la collection alors il y a toujours un élément à l'index 0. –

+0

@Stan R - c'est une boucle while, donc il ne sera pas besoin d'un indexeur – GenericTypeTea

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

c'est un mauvais code, regardez d'autres explications. –

+2

vous plaisantez? –

+0

Il fonctionne (j'ai vu l'option claire après que j'ai posté) – Crash893

0

vous pouvez réellement pas utiliser Remove car il brise la iterator solution si simple serait quelque chose comme ceci:

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

mais Bien sûr, vous ne voulez pas coller à Loop, alors allez-y et utilisez panel1.Controls.Clear()

+0

Bien sûr, cela ne fonctionnerait pas car lorsque vous supprimez un contrôle, vous modifiez l'index des contrôles existant. Vous bouclez trop. Imaginez avoir 2 contrôles votre boucle dit commencer à 0 et finir à l'index = 2. La minute où vous supprimez un contrôle que vous avez réellement changé l'index de tous les contrôles actuels. La solution consiste simplement à boucle pour le nombre de contrôles mais enlever à l'index 0. int n; n = panel1.Controls.Count-1; for (int i = 0; i <= n; i ++) { contrôle c = panel1.Controls [0]; panel1.Controls.Remove (c); } – JonH

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); 
    } 
} 

Une autre façon!

Questions connexes