我有一个带有代码的Windows表单,可以动态创建TextBoxes。当满足某些条件时,将创建TextBoxes,所有文本框的名称都以&#34开头; TextBoxRep"并在背面附上一个唯一的ID,例如" TextBoxRep112"或" TextBoxRep234"。
现在,当不再满足这些特定条件时(可能发生),我希望能够删除这些TextBox。我目前的代码如下:
For Each ctrl As Control In Me.Controls
If ctrl.Name.StartsWith("LabelRep") Then
Me.Controls.Remove(ctrl)
End If
If ctrl.Name.StartsWith("TextBoxRep") Then
Me.Controls.Remove(ctrl)
End If
Next
它基本上循环遍历Windows窗体中的每个控件,如果控件名称以" TextBoxRep"开头。我将其从控件列表中删除。
问题是,remove()似乎是随机的。控件被删除,但不是所有控件同时删除;有时,只有一些被删除,并且必须反复运行循环才能正确删除所有TextBox。实际上,在一些.Remove()函数调用之后,For循环似乎被打破了。
这里发生了什么?
答案 0 :(得分:0)
一个棘手的问题是你在迭代它时改变了枚举(Me.Control
)。这会跳过每一秒的控制。
你的循环执行以下操作:
假设您的枚举包含三个控件Tb1, Tb2, Tb3
。一开始它看起来像这样:
0 :Tb1, 1 :Tb2, 2 :Tb3
迭代1 ,循环处于索引 0 :
-->
在索引 0 处查找Tb1,将其删除-->
0 :Tb2, 1 :Tb3
循环进入迭代2 ,它现在处于索引 1 :
-->
在索引 1 处查找Tb3,将其删除-->
0 :Tb2
循环现在在当前索引之后找不到更多项,因此它结束。 Tb2留在列表中。
在迭代过程中永远不要更改枚举!您可以通过从最后一个索引开始并在删除时继续前进来侥幸逃脱,但它的一切都很糟糕。 而是首先选择要删除的控件,然后在第二次删除它们:
Dim ToRemove As New List(Of Control)
For Each c As Control In Me.Controls
If TypeOf (c) Is TextBox AndAlso c.Name.StartsWith("TextboxRep") Then ToRemove.Add(c)
Next
For Each c As Control In ToRemove
Me.Controls.Remove(c)
Next