移除动态控制
Remove dynamic control
我有一个带有动态添加控件的表单。当用户单击下一步时,必须删除所有动态控件。我的代码只删除了其中的一些。
例如 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();
}
这是我的移除函数
void removeDynamics()
{
foreach (Control x in this.Controls)
{
if (x.Name.Contains("Dynamic"))
{
this.Controls.Remove(x);
x.Dispose();
}
}
}
您在迭代 Controls
集合的同时修改它。您可以使用 LINQ 的 ToList()
生成一个您可以迭代的单独集合。
void removeDynamics()
{
foreach (Control x in this.Controls.OfType<TextBox>().ToList())
{
if (x.Name.Contains("Dynamic"))
{
this.Controls.Remove(x);
x.Dispose();
}
}
}
事实上,因为您现在正在使用 LINQ。您不妨只拉动您想要的控件:
void removeDynamics()
{
foreach (Control x in this.Controls.Where(x => x.Name.StartsWith("Dynamic")).ToList())
{
this.Controls.Remove(x);
x.Dispose();
}
}
for example dtxt2 does not get removed the first time but if I run the remove function a second time it does get removed.
... if you have time could you further explain what my fault was?
当你遍历一个集合时,你在后台有一个迭代器,它保存当前位置并根据集合的长度进行检查。那么如果集合有3个item,迭代器在位置2
[X1] [X2] [X3] // Length 3
^
|
iterator
现在你删除第二个元素
[X1] [X3] // Length 2
^
|
iterator
迭代器仍然有它的值,但现在它指向下一个元素,不幸的是这是集合中的最后一个。现在循环将递增迭代器并检查它是否已经大于集合中的项目数量。如果是这样,它将取消循环,因为没有更多的项目可以迭代。因此 X3 永远不会被处理
[X1] [X3] // Length 2
^
|
iterator
这就是为什么您的第二个文本框首先被跳过的原因。
在通过集合进行迭代期间从集合中删除项目时,可以使用反向循环。从末尾开始到 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();
}
}
}
当然你也可以过滤控件集合,只获取匹配的项,然后删除它们:
List<TextBox> toBeRemoved = this.Controls.OfType<TextBox>()
.Where(x => x.Name.Contains("Dynamic")).ToList();
toBeRemoved.ForEach(x => { this.Controls.Remove(x); x.Dispose(); });
我有一个带有动态添加控件的表单。当用户单击下一步时,必须删除所有动态控件。我的代码只删除了其中的一些。
例如 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();
}
这是我的移除函数
void removeDynamics()
{
foreach (Control x in this.Controls)
{
if (x.Name.Contains("Dynamic"))
{
this.Controls.Remove(x);
x.Dispose();
}
}
}
您在迭代 Controls
集合的同时修改它。您可以使用 LINQ 的 ToList()
生成一个您可以迭代的单独集合。
void removeDynamics()
{
foreach (Control x in this.Controls.OfType<TextBox>().ToList())
{
if (x.Name.Contains("Dynamic"))
{
this.Controls.Remove(x);
x.Dispose();
}
}
}
事实上,因为您现在正在使用 LINQ。您不妨只拉动您想要的控件:
void removeDynamics()
{
foreach (Control x in this.Controls.Where(x => x.Name.StartsWith("Dynamic")).ToList())
{
this.Controls.Remove(x);
x.Dispose();
}
}
for example dtxt2 does not get removed the first time but if I run the remove function a second time it does get removed.
... if you have time could you further explain what my fault was?
当你遍历一个集合时,你在后台有一个迭代器,它保存当前位置并根据集合的长度进行检查。那么如果集合有3个item,迭代器在位置2
[X1] [X2] [X3] // Length 3
^
|
iterator
现在你删除第二个元素
[X1] [X3] // Length 2
^
|
iterator
迭代器仍然有它的值,但现在它指向下一个元素,不幸的是这是集合中的最后一个。现在循环将递增迭代器并检查它是否已经大于集合中的项目数量。如果是这样,它将取消循环,因为没有更多的项目可以迭代。因此 X3 永远不会被处理
[X1] [X3] // Length 2
^
|
iterator
这就是为什么您的第二个文本框首先被跳过的原因。
在通过集合进行迭代期间从集合中删除项目时,可以使用反向循环。从末尾开始到 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();
}
}
}
当然你也可以过滤控件集合,只获取匹配的项,然后删除它们:
List<TextBox> toBeRemoved = this.Controls.OfType<TextBox>()
.Where(x => x.Name.Contains("Dynamic")).ToList();
toBeRemoved.ForEach(x => { this.Controls.Remove(x); x.Dispose(); });