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
精彩评论