Foreach loop to remove iterative controls

Code for creating text fields ...

private void btnAddIncrement_Click(object sender, EventArgs e) { SmartTextBox dynamictextbox = new SmartTextBox(); dynamictextbox.BackColor = Color.Bisque; dynamictextbox.Width = this.tbWidth; dynamictextbox.Left = (sender as Button).Right + this.lastLeft; dynamictextbox.K = "Test"; this.lastLeft = this.lastLeft + this.tbWidth; dynamictextbox.Top = btnAddStart.Top; this.Controls.Add(dynamictextbox); } 

Code to delete all text fields.

 foreach (Control c in this.Controls) { if (c.GetType() == typeof(BnBCalculator.SmartTextBox)) { count++; //MessageBox.Show((c as SmartTextBox).K.ToString()); c.Dispose(); } // else { MessageBox.Show("not txtbox"); } } 

When I click btnAddIncrement, I get the following as expected ... enter image description here

But when I press reset, it skips every second text field. See below...

enter image description here

I don’t know what is going on here, but it’s the same thing no matter how you add text fields. He always skips every second box.

+6
c # winforms
source share
5 answers

You must use the inverse standard for the loop to pull SmartTextBoxes out of its container

 for(int x = this.Controls.Count - 1; x >= 0; x--) { BnBCalculator.SmartTextBox c = this.Controls[x] as BnBCalculator.SmartTextBox; if (c != null) { count++; c.Dispose(); } } 

In accordance with this question / answer, you do not need to remove them from the container, and, of course, this avoids two loops (explicit or implicit). Also in the accepted answer you can see the reason why your code skips every two.

 if (parent != null) { parent.Controls.Remove(this); } 

The control you want to delete is removed from the collection that you are executing. (It is not clear why this does not throw a standard exception).

Instead, a loop with a simple reverse order eliminates any problem in the ordered access to controls that need to be disposed of.

+7
source share

The deletion code is incorrect because you are modifying the Controls collection by calling Dispose() , so you get skipped controls.

The easiest way to remove those that are of a particular type is as follows:

 var smartTbs = this.Controls.OfType<BnBCalculator.SmartTextBox>().ToList(); smartTbs.ForEach(x => x.Dispose()); 
+2
source share

When you delete the form of the this.Controls element, the collection changes, so the next element is not what you expect. Yo should copy this.Controls to a new list. For example, you can use ToArray to make a copy of this.Controls

 foreach (Control c in this.Controls.ToArray()) { ... } 
+2
source share

You must first remove the controls from Form.Controls, and then remove it.

 var controlsToRemove = new List<Control>(); foreach (Control c in this.Controls) { if (c is BnBCalculator.SmartTextBox) controlsToRemove.Add(c); } foreach (Control c in controlsToRemove) { Controls.Remove(c); } 
+1
source share

Try first selecting all the SmartTextBox controls and disposing of them in a different loop. Pseudocode:

  SmartTextBoxes = Select From this.Controls Where (c.GetType() == typeof(BnBCalculator.SmartTextBox)); foreach(stb in SmartTextBoxes) { stb.Dispose(); } 
0
source share

All Articles