VB.NET Filtering ListItems Problem

后端 未结 5 681
北荒
北荒 2021-01-25 11:15

I am trying to filter a ListBox based on the presence of a string. Basically, if there is a ListItem that doesn\'t contain the string then I want to remove all ListItems that do

相关标签:
5条回答
  • 2021-01-25 11:25

    Why don't you filter the items before they are placed in the listbox?

    0 讨论(0)
  • 2021-01-25 11:29

    When removing items from a list there are a couple of options. As you've discovered, modifying the collection in a foreach loop isn't going to work. A for loop that counts down is the answer as @balpha mentioned.

    Another option is to store a list of items in a separate list, then iterate over that to remove items from the original list. Yet another option is to use LINQ.

    Sample list:

    Dim stringList As New List(Of String)
    stringList.Add("W:foo")
    stringList.Add("bar")
    stringList.Add("barW:")
    stringList.Add("foo")
    

    Reverse For Loop

    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

    In this snippet I filter on IndexOf = -1 instead of > -1 to keep what I want rather than filter what I don't want.

    stringList = stringList.Where(Function(s) s.IndexOf("W:") = -1).ToList()
    
    0 讨论(0)
  • 2021-01-25 11:33

    Try reversing your loop, i.e. start from the end of the list. That way, deleting items won't shift the index of the remaining items you still have to check (which is the cause of your out of range exception).

    The first way causes a problem because you're modifying the list while iterating over it. And that is, as you said, a big no-no.

    0 讨论(0)
  • 2021-01-25 11:48

    Based on balpha's help above, this is what I ultimately did:

    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
    
    0 讨论(0)
  • 2021-01-25 11:50

    Let suppose the filter string is a textbox string and you want to filter your listbox according to the text changed in textbox. Let the name of the textbox is TB_Filter.

    Place this line of code from the top of your codes, after Public Class Form1 to temporary hold your listbox items.

    Dim TempHoldMyItems As New ArrayList
    

    Now use this piece of codes in your form_load event to update the temporary list from your listbox items.

    TempHoldMyItems.Clear()
    TempHoldMyItems.AddRange(listbox1.Items)
    

    Ok, Now you can filter your listbox items according to the text in TB_Filter. Use this codes in TB_Filter Text Changed event.

    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
    

    This will filter items in listbox1 as you will type in TB_Filter. This will match starting of your items with your filter word in TB_Filter.

    By making little changes (i.e. Instead of substring you may use contains property) to check filter query is contains in item.

    listbox1.Items.Clear()
    For Each item As String In TempHoldMyItems
        If item.Contains(TB_Filter.Text) Then
            listbox1.Items.Add(item)
        End If
    Next
    
    0 讨论(0)
提交回复
热议问题