开发者

Removing items from a ListView

开发者 https://www.devze.com 2022-12-18 13:17 出处:网络
I am trying to search through listview in VB.net 2008. It works fine with small list, but when the list is big ( around 25000 rows), if I search multiple items , it fails saying that index is not vali

I am trying to search through listview in VB.net 2008. It works fine with small list, but when the list is big ( around 25000 rows), if I search multiple items , it fails saying that index is not valid. Obviously what I understand is , it it tryiong to remove an index does not exist. But I am unable to figure out where exactly it is going wrong. Can anyone please help?

PS : while it is doing search through the entire listview, I am incrementing index = index+5 becasue I want the next 5 rows to be in the selection state as well.

This is the code :

Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
    If (e.KeyCode = Keys.PageDown) Then
            'ListView1.Items.Clear()
            Dim s As String
            Dim index As Integer
            Dim item As String


            ListView1.BeginUpdate()

            Try
                ' keep track of the "non-searched items" '
                Dim indicesToRemove As New List(Of Integer)

                ListView1.SelectedIndices.Clear()
                If TextBox1.Text.Length > 0 Then
                    Dim lstOfStrings() As String = TextBox1.Text.Split(","c)

                    For Each s In lstOfStrings

                开发者_JAVA技巧        For index = 0 To ListView1.Items.Count - 1

                            If s.Trim() <> "" Then
                                item = ListView1.Items(index).ToString()

If item.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) >= 0 Then

                                    ListView1.SelectedIndices.Add(index)
                                    index = index + 5
                                    'ListView1.SelectedIndices.Add(index)


                                Else
                                    ' this item was not searched for; we will remove it '
                                    indicesToRemove.Add(index)
                                End If
                            End If

                        Next

                        ' go backwards to avoid problems with indices being shifted '
                        For i As Integer = indicesToRemove.Count - 1 To 0 Step -1
                            Dim indexToRemove As Integer = indicesToRemove(i)
                    ListView1.Items.RemoveAt(indexToRemove) ' blowing on this line
                        Next

                    Next s

                End If
            Finally
                ListView1.EndUpdate()
            End Try
End Sub

Thanks.


IMO, there are quite a lot of things which need fixing in this code... but an easy fix that will solve your problem is this: instead of grabbing the list item indices to remove, keep an array of the list items themselves, then simply call the Remove method on each one. That way you don't even need to deal with indices and ordering.

Edit: and I think the For Each s In lstOfStrings should be nested inside the list item iteration. That could be a big part of the problem.

Edit 2: You might want to give us a sense of what you're trying to accomplish with this code, because there is a LOT going on in it that doesn't make much sense.

Edit 3: I made a test project with a ListView, a TextBox, and a Button, and added some random items to the ListView in Form_Load. The logic still isn't making 100% sense to me, but I'm not getting any crashes.

Edit 4: Simplified the code. Removed the index = index + 5 stuff.

Edit 5: Back to the other code. Reimplemented the weird index selection thing.

Edit 6: Finally?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If TextBox1.Text.Trim().Length = 0 Then Exit Sub

    ' keep track of the "non-searched items" '
    Dim itemsToRemove As New List(Of ListViewItem)

    ListView1.BeginUpdate()
    ListView1.SelectedIndices.Clear()

    If TextBox1.Text.Length > 0 Then
        Dim lstOfStrings() As String = TextBox1.Text.Split(","c)

        For index As Integer = 0 To ListView1.Items.Count - 1
            For Each s As String In lstOfStrings
                Dim realS As String = s.Trim()

                If realS  "" Then
                    Dim item As ListViewItem = ListView1.Items(index)

                    If item.Text.IndexOf(realS, StringComparison.CurrentCultureIgnoreCase) >= 0 Then
                        Dim i As Integer = 1

                        While (i + index < ListView1.Items.Count) And (i <= 5)
                            ListView1.SelectedIndices.Add(i + index)
                            i = i + 1
                        End While

                        index = index + 5

                        Exit For
                    Else
                        ' this item was not searched for; we will remove it '
                        itemsToRemove.Add(item)
                    End If
                End If
            Next s
        Next index

        For Each i As ListViewItem In itemsToRemove
            ListView1.Items.Remove(i)
        Next i
    End If

    ListView1.EndUpdate()
End Sub


Try this. Like Jon says, it's a lot easier to use the listitem itself instead of the index. With the for each item loop you can just delete them as you go. Incidentally, I recommend some kind of message or breakpoint and the end of a try block, especially one that big.

Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp

  If (e.KeyCode = Keys.PageDown) Then
    'ListView1.Items.Clear()
    Dim s As String
    Dim item As ListViewItem
    Dim found As Boolean

    ListView1.BeginUpdate()

    Try
        ' keep track of the "non-searched items" '
        Dim indicesToRemove As New List(Of Integer)

        ListView1.SelectedIndices.Clear()
        If TextBox1.Text.Length > 0 Then
          Dim lstOfStrings() As String = TextBox1.Text.Split(","c)
          For Each item In ListView1.Items
            found = False
            For Each s In lstOfStrings
              If String.Compare(s, item.Text, True) = 0 Then
                found = True
                Exit For
              End If
            Next s
          If Not found Then ListView1.Items.Remove(item)
          Next item
        End If

    Catch ex As Exception
      MsgBox(ex.Message)
    Finally
      ListView1.EndUpdate()
    End Try
  End If
End Sub
0

精彩评论

暂无评论...
验证码 换一张
取 消