我正在尝试根据字符串的存在过滤ListBox。基本上,如果有一个ListItem不包含该字符串,那么我想删除所有包含该字符串的ListItem。这是我尝试过的:
Dim Item As ListItem
For Each Item In CtheList.Items
If Item.Text.IndexOf("W:") = -1 Then
CtheList.Items.Remove(Item)
End If
Next
这显然是禁忌,因为它会产生错误:收集被修改;枚举操作可能无法执行。
我也尝试过:
Dim Item As ListItem
For Each Item In CtheList.Items
If Item.Text.IndexOf("W:") = -1 Then
Dim i As Integer
For i = 0 To CtheList.Items.Count - 1
If CtheList.Items.Item(i).Text.IndexOf("W:") > -1 Then
CtheList.Items.RemoveAt(i)
End If
Next i
End If
Next
这会生成超出范围异常的索引。
非常感谢任何帮助。
答案 0 :(得分:3)
尝试反转循环,即从列表末尾开始。这样,删除项目不会改变您仍需要检查的剩余项目的索引(这是您超出范围异常的原因)。
第一种方式会导致问题,因为您在迭代时修改列表。就像你说的那样,这是一个很大的禁忌。
答案 1 :(得分:2)
从列表中删除项目时,有几个选项。正如您所发现的那样,在foreach循环中修改集合是行不通的。倒计时的for循环是@balpha提到的答案。
另一种选择是将项目列表存储在单独的列表中,然后对其进行迭代以从原始列表中删除项目。另一种选择是使用LINQ。
示例清单:
Dim stringList As New List(Of String)
stringList.Add("W:foo")
stringList.Add("bar")
stringList.Add("barW:")
stringList.Add("foo")
反向循环
For i As Integer = stringList.Count - 1 To 0 Step -1
If stringList(i).IndexOf("W:") > -1 Then stringList.RemoveAt(i)
Next
ForEach with 2 Lists
Dim removeList As New List(Of String)
' store items to remove here
For Each s As String In stringList
If s.IndexOf("W:") > -1 Then removeList.Add(s)
Next
' remove stored items here
For Each s As String In removeList
stringList.Remove(s)
Next
<强> LINQ 强>
在此代码段中,我对IndexOf = -1进行过滤,而不是&gt; -1保持我想要的东西而不是过滤我不想要的东西。
stringList = stringList.Where(Function(s) s.IndexOf("W:") = -1).ToList()
答案 2 :(得分:1)
根据上面的balpha的帮助,这就是我最终做的事情:
Dim StringPresent As Boolean = False
Dim Item As ListItem
For Each Item In CtheList.Items
If Item.Text.IndexOf("W:") = -1 Then
StringPresent = True
Exit For
End If
Next
If StringPresent = True Then
Dim i As Integer
For i = CtheList.Items.Count - 1 To 0 Step -1
If CtheList.Items.Item(i).Text.IndexOf("W:") > -1 Then
CtheList.Items.RemoveAt(i)
End If
Next i
End If
答案 3 :(得分:0)
为什么不在将项目放入列表框之前对其进行过滤?
答案 4 :(得分:0)
假设过滤字符串是文本框字符串,并且您希望根据文本框中更改的文本过滤列表框。让文本框的名称为TB_Filter
。
在Public Class Form1
之后,从代码顶部放置此行代码,暂时保留您的列表框项目。
Dim TempHoldMyItems As New ArrayList
现在在form_load事件中使用这段代码来更新列表框项目中的临时列表。
TempHoldMyItems.Clear()
TempHoldMyItems.AddRange(listbox1.Items)
好的,现在您可以根据TB_Filter中的文本过滤列表框项目。在TB_Filter Text Changed事件中使用此代码。
listbox1.Items.Clear()
For Each item As String In TempHoldMyItems
If item.Length >= TB_Filter.Text.Length Then
If item.Substring(0, TB_Filter.Text.Length) = TB_SearchInSelected.Text Then
listbox1.Items.Add(item)
End If
End If
Next
这将过滤您在TB_Filter中输入的listbox1中的项目。这会将您的商品的开头与TB_Filter中的过滤字匹配。
通过进行少量更改(即代替substring
,您可以使用contains
属性)来检查过滤查询是否包含在项目中。
listbox1.Items.Clear()
For Each item As String In TempHoldMyItems
If item.Contains(TB_Filter.Text) Then
listbox1.Items.Add(item)
End If
Next