用于处理跳过迭代的控件的Foreach循环

时间:2016-01-29 11:50:29

标签: c# winforms

创建文本框的代码......

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

删除所有文本框的代码。

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

}

当我点击btnAddIncrement时,我按预期得到以下内容...... enter image description here

但是当我点击重置时,它会错过每一个文本框。见下文......

enter image description here

不知道这里发生了什么,但无论我添加的文本框怎么样,这都是一样的。它总是错过每一个盒子。

5 个答案:

答案 0 :(得分:7)

您应该使用反向标准for循环来处理其容器中的SmartTextBox

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

According to this question/answer你不需要从容器中删除它们,当然这避免了两个循环(显式或隐式)。同样在接受的答案中,您可以看到代码每两次跳转一个控件的原因。

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

要迭代的控件将从您正在迭代的集合中删除。 (不清楚为什么这不会抛出标准异常)。

而是使用简单的反向循环,以避免对要处置的控件的有序访问中的任何问题。

答案 1 :(得分:2)

您的删除代码不正确,因为您通过调用Controls来修改Dispose()集合,这就是您跳过控件的原因。

删除特定类型的最简单选项是执行以下操作:

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

答案 2 :(得分:2)

当您删除项目表单this.Controls时,该集合已被修改,因此下一个项目不符合您的预期。哟应该将this.Controls复制到新列表中。例如,您可以使用ToArray制作this.Controls

的副本
foreach (Control c in this.Controls.ToArray())
{
    ...
}

答案 3 :(得分:1)

首先必须从Form.Controls中删除控件,然后将其处理掉。

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

答案 4 :(得分:0)

首先尝试选择所有SmartTextBox控件并将它们放在另一个循环上。伪代码:

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