移除动态控制

Joe*_*i E 2 c# windows-forms-designer winforms

我有一个带有动态添加控件的表单。当用户单击 next 时,必须删除所有动态控件。我的代码只删除了其中的一些。

例如dtxt2,第一次不会被删除,但如果我第二次运行删除功能,它会被删除。

这是添加动态的函数:


void TextboxesStep21()
{
    removeDynamics();
     TextBox dtxt1 = new TextBox();
     dtxt1.Name = "DynamicTextBox1";
     dtxt1.Location = new System.Drawing.Point(336, 125);
     dtxt1.Text = ((diameterOfDrivingWeel + spindleSlope)*10).ToString();
     this.Controls.Add(dtxt1);
     
    TextBox dtxt2 = new TextBox();
    dtxt2.Name = "DynamicTextBox2";
    dtxt2.Location = new System.Drawing.Point(336, 148);
    dtxt2.Text = gearingRatioDen.ToString();
    this.Controls.Add(dtxt2);

    TextBox dtxt3 = new TextBox();
    dtxt3.Name = "DynamicTextBox3";
    dtxt3.Text = gearingRatioNum.ToString(); ;
    dtxt3.Location = new System.Drawing.Point(336, 171);
    this.Controls.Add(dtxt3);


    pictureBox1.SendToBack();
    pictureBox2.SendToBack();
}

Run Code Online (Sandbox Code Playgroud)

这是我的删除功能

void removeDynamics()
{
    foreach (Control x in this.Controls)
    {
        if (x.Name.Contains("Dynamic"))
        {
            this.Controls.Remove(x);
            x.Dispose(); 
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

Mon*_*Zhu 5

例如 dtxt2 第一次不会被删除,但如果我第二次运行删除功能,它会被删除。
......如果你有时间,你能进一步解释我的错吗?

当您遍历一个集合时,您在后台有一个迭代器,它保存当前位置并根据集合的长度进行检查。因此,如果集合有 3 个项目并且迭代器位于位置 2

[X1] [X2] [X3]  // Length 3
      ^
      |
   iterator
Run Code Online (Sandbox Code Playgroud)

现在删除第二个元素

[X1] [X3]  // Length 2
      ^
      |
   iterator
Run Code Online (Sandbox Code Playgroud)

迭代器仍然有它的值,但现在它指向下一个元素,不幸的是这是集合中的最后一个。现在循环将增加迭代器并检查它是否已经大于集合中的项目数量。如果是这样,它将取消循环,因为没有更多要迭代的项目。X3 因此永远不会被处理

[X1] [X3]      // Length 2
           ^
           |
        iterator
Run Code Online (Sandbox Code Playgroud)

这就是为什么您的第二个文本框首先被跳过的原因。

在迭代过程中从集合中删除项目时,将使用反向循环。从末尾开始并下降到 0:

void removeDynamics()
{
    for (int i = this.Controls.Count - 1; i >= 0; i--)
    {
        Control x = this.Controls[i];
        if (x.Name.Contains("Dynamic"))
        {
            this.Controls.Remove(x);
            x.Dispose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您当然也可以过滤控件集合并首先仅获取匹配的项目,然后将其删除:

List<TextBox> toBeRemoved = this.Controls.OfType<TextBox>()
                                         .Where(x => x.Name.Contains("Dynamic")).ToList();
toBeRemoved.ForEach(x => { this.Controls.Remove(x); x.Dispose(); });
Run Code Online (Sandbox Code Playgroud)