从循环中删除集合中的项目(组合框项目) [英] Remove Items from Collection in a loop (Combo Box items)
问题描述
我试图从以〜$开头的组合框列表中删除所有项目。
As String In cstmcmbxDocs.Items
如果不是cstmcmbxDocs.Items.Contains(〜$)则
Dim STR As Int16 = cstmcmbxDocs.FindString(〜$)
'包含〜$的项目
cstmcmbxDocs.Items.RemoveAt([STR])
结束如果
下一页
但它只返回一个它删除的实例。
它不继续搜索 - 我在这里丢失了什么?
(请注意,我使用的是3.5而不是4+,因为它需要与XP兼容)
在使用For Each / Next时,无法修改集合(添加或删除)。也不能使用标准 For n As Int32
循环。而是:
For n As Int32 = cstmcmbxDocs.Items。计数-1到0步骤-1
...
如果[您的标准在这里]然后
cstmcmbxDocs.Items.RemoveAt(n)'删除当前一个
结束如果
Next n
您还应该打开Option Strict: Dim STR As Int16 = cstmcmbxDocs.FindString(〜$)
无法编译。而且你不需要使用 FindString
- 你的循环已经在查看每个项目,所以只需检查每个条件。
为什么每个循环失败
对于每个项目作为字符串在cstmcmbxDocs.Items
导致 InvalidOperationException
。如果您点击获取常规帮助链接,您会发现:
- When(n = 2)Gamma是当前项目。
- 您的代码
RemoveAt(n)
,所以一切都向上移动。n 现在指向Delta
- 然后
$ c> n
现在指向回声
循环,因为它被跳过。删除的每个元素将被跳过。这是MSDN意味着枚举器不可恢复地无效
在这种情况下,你的循环也会用完项目!仅在循环开始时才计算结束循环值 lst.Count - 1
。删除项目会减少实际大小,因此最终会与 ArgumentOutOfRangeException
崩溃。与以前一样,使用
End If
Next
>现在,当项目删除时,重新排序的列表部分是代码已经测试的部分。
I am trying to remove all items from a combo box list that begin with "~$".
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
But it only returns one instance which it removes. It doesn't continue searching - what am i missing here? (Note that I am using 3.5 and not 4+ because it needs to be compatible with XP)
You cannot modify a collection (add or delete) as you iterate using For Each/Next. Nor can you use a standard For n As Int32
loop. Instead:
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
You should also turn on Option Strict: Dim STR As Int16 = cstmcmbxDocs.FindString("~$")
wont compile. And you do not need to use FindString
- your loop is already going to look at each item, so just examine each for the condition.
Why a For Each loop fails
For Each item As String In cstmcmbxDocs.Items
Removing from inside this type of loop should result in an InvalidOperationException
. If you click the Get general help link you find this:
An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException.
Why a forward For n loop will fail
Consider:
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
- When (n=2) "Gamma" is the current item.
- Your code
RemoveAt(n)
so everything moves up one.n
now points to "Delta" - Then
Next
incrementsn
so it now points to "Echo"
"Delta" is never evaluated in the loop because it is skipped. Every element after a deleted one will be skipped. This is what MSDN means by enumerator is irrecoverably invalidated
.
In this case, your loop will also run out of items! The end loop value, lst.Count - 1
is calculated only at the start of the loop. Removing items reduces the actual size so it will eventually crash with an ArgumentOutOfRangeException
. As before, loop backwards using 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
Now, when items are removed, the part of the list which is reordered is the part the code has already tested.
这篇关于从循环中删除集合中的项目(组合框项目)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!