tags:

views:

116

answers:

2

Hi,

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

                        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.

+2  A: 

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
Jon Seigel
array means list?
JPro
Yes, of type `ListViewItem`.
Jon Seigel
can you please give me sample code to store items in list from listview?
JPro
Instead of `item = ListView1.Items(index).ToString()` (which returns a string), declare `item as ListViewItem` and assign it using `item = ListView1.Items(index)`.
Jon Seigel
What I am trying to achive is : I want the user to be able to search through multiple items given in the textbox separated by comma, then page down is pressed, all the items in the listview should be removed except the searched items ( one or more) . Hope this makes sense
JPro
Okay. If you remove the `index = index + 5` line in my code, it works fine. How does the `index + 5` stuff enter the picture? Do you have some kind of parent/child items in your ListView?
Jon Seigel
no parent or child, or not sure what it is, but I am trying to select the next 5 rows and the way I am selecting is adding the index to 5. This is what I guess the problem is
JPro
the above code gives me an error :`item As ListViewItem = ListView1.Items(index)`
JPro
Fixed the code to do the selection thing. Try again now.
Jon Seigel
still error at : `item As ListViewItem = ListView1.Items(index)`I really appreciate your patience.
JPro
What value of `index` is causing it to fail? (Use the debugger to help you.)
Jon Seigel
`Additional information: InvalidArgument=Value of '30' is not valid for 'index'.` for list items of 28 items, one row space
JPro
I'm sorry, I'm unable to reproduce the error. Are you sure you copied the code correctly? I had been tinkering with small parts of it between my edits.
Jon Seigel
Sorry for the delay. It is working fine for one searched term. But I am trying to search 2 items , and the application is still running without any response. It does not even hang. Still going on ...
JPro
D'OH! I only tried one search term, and now I'm getting the crash with 2.
Jon Seigel
I added an Exit For in there. That should do it. I assumed you want matched items to match at least one of the search terms.
Jon Seigel
no luck, it is crashing with `Managed Debugging Assistant 'ContextSwitchDeadlock' has detected a problem in 'C:\Documents and Settings\JPro\My Documents\Visual Studio 2008\Projects\Copy\WindowsApplication1\bin\Debug\WindowsApplication1.vshost.exe'.`
JPro
That doesn't look like an error related to the code here...
Jon Seigel
I am loading a file around 2mb and this is when it is crashing
JPro
Yeah. Since that is a separate issue, try to resolve it on your own, and if you can't figure out how to fix it, you can ask a new question on here.
Jon Seigel
ok. Thank you very much for your patience
JPro
You're welcome. If you're still having trouble with this part of the program, feel free to come back to this question.
Jon Seigel
A: 

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
xpda