我正在尝试从以"〜$"开头的组合框列表中删除所有项目。
For Each item As String In cstmcmbxDocs.Items
If Not cstmcmbxDocs.Items.Contains("~$") Then
Dim STR As Int16 = cstmcmbxDocs.FindString("~$")
'gets the index of the item which contains "~$"
cstmcmbxDocs.Items.RemoveAt([STR])
End If
Next
但它只返回一个删除的实例。 它不会继续搜索 - 我在这里缺少什么? (请注意,我使用的是3.5而不是4+,因为它需要与XP兼容)
答案 0 :(得分:4)
在使用For Each / Next进行迭代时,无法修改集合(添加或删除)。你也不能使用标准For n As Int32
循环。代替:
For n As Int32 = cstmcmbxDocs.Items.Count -1 To 0 Step -1
...
If [your criteria here] Then
cstmcmbxDocs.Items.RemoveAt(n) ' remove current one
End If
Next n
你也应该打开Option Strict:Dim STR As Int16 = cstmcmbxDocs.FindString("~$")
不会编译。而且您不需要使用FindString
- 您的循环已经开始查看每个项目,因此只需检查每个项目。
For Each item As String In cstmcmbxDocs.Items
从这种类型的循环内部删除应该会产生InvalidOperationException
。如果您单击获取常规帮助链接,您会发现:
只要集合保持不变,枚举器仍然有效。如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且下一次调用MoveNext或Reset会引发InvalidOperationException。
考虑:
Dim lst As New List(Of String)
lst.AddRange(New String() {"Alpha", "Beta", "Gamma", "Delta", "Echo"})
For n As Int32 = 0 To lst.Count - 1
If lst(n) = "Gamma" OrElse lst(n) = "Delta" Then
lst.RemoveAt(n)
End If
Next
RemoveAt(n)
所以一切都向上移动了。 n
现在指向“Delta”Next
递增n
,现在它指向“Echo”“Delta”永远不会在循环中进行评估,因为它会被跳过。删除后面的每个元素都将被跳过。这就是MSDN在enumerator is irrecoverably invalidated
中的含义。
在这种情况下,你的循环也将耗尽项目!结束循环值lst.Count - 1
仅在循环开始时计算。删除项目会减小实际大小,因此最终会导致ArgumentOutOfRangeException
崩溃。和以前一样,使用For n
循环向后:
For n As Int32 = lst.Count - 1 To 0 Step - 1
If lst(n) = "Gamma" OrElse lst(n) = "Delta" Then
lst.RemoveAt(n)
End If
Next
现在,当删除项目时,重新排序的列表部分是代码已经测试的部分。