Alright, I did a search on vb forums and found something that helped me out:
vb Code:
Dim itmX As ListViewItem = lstStudents.FindItemWithText(tstSearch.Text, False, 0)
If Not itmX Is Nothing Then
lstStudents.Focus()
itmX.Selected = True
lstStudents.Items(itmX.Index).Selected = True
itmX.EnsureVisible()
End If
So here's the problem know. When have more than 1 of the same text (say, Last Name or First Name) Then it will only do the very last item, instead of starting with the FIRST item & then when I click the search Button again, it will go to the next item in the List with that Text.
I don't know why it would select the last item but if you want to make it select the next item with the same search text you will need to keep track of the last search text and the last item/index that you found with that search. That way if the user presses the button again with the same search you can pick up where you left off...
something like this:
Code:
If lastSearch = tstSearch.Text Then
itmX = lstStudents.FindItemWithText(tstSearch.Text, False, lastIndex + 1)
Else
itmX = lstStudents.FindItemWithText(tstSearch.Text, False, 0)
End If
lastIndex = itmX.Index
lastSearch = tstSearch.Text
'your other code...
Can you clarify what you're looking for? As I understand it, you have a ListView which you would like to search. It's possible that the listview contains multiple items with the same text value. When this is the case when the user searches you would like to highlight the first item. Then if the user performs the same search again by clicking the button again you want to highlight the second item in the listview that matches the search. Is this right?
I'd have to go with what wy125 says, his code looks okay, and I don't know why that shouldn't work.
I'm not quite sure what you want, do you want it to find the last item first, or is that what the program does, and you don't want that at all? From your question, I think you want it to find the last result.
If so, I think you should use a loop to go through all the results, and remember the last index, and then use listview.findItemWithText(seach.text,false,lastindex)
If not: I haven't got a clue why it gives you the last result instead of the first.
okay i just whipped together something so i could test it.. It seems to work pretty well. You will probably want to tweak this to get it to do exactly what you want.
First you need to have two fields in your class, one for the lastSearch text and the other for the index of the last item found:
Code:
Public Class Form1
Private lastSearch As String
Private lastIndex As Integer = -1
....
then when the user clicks the button you can do something like this:
vb Code:
Dim searchText As String = txtSearch.Text.Trim()
Dim lvItem As ListViewItem = Nothing
'don't bother with empty searches
If searchText = "" Then
Return
End If
'clear previously selected itmes
If (listView.SelectedItems.Count > 0) Then
listView.SelectedItems(0).Selected = False
End If
'check if the lastSearch is the same as current one
'also check if we've reached the last item
'the second check, lastIndex < listView.Items.Count - 1, makes sure we don't
'go beyond the indices of the listview
'the way it is now, if we reach the last item in the search it will go back to the
'first item
If searchText = lastSearch And lastIndex < listView.Items.Count - 1 Then
'we need to continue where we left off, search 1 ahead of where we last found
it checks to make sure that lvItem isn't null (the search turned up empty). If it was null and you tried to read the index and highlight it you would get an exception.
What happens is when I have 3+ Items (it work fine) but when I have 2 Items it Selects the First then the Second but doesn't go back to the Beginning like the 3+ Items.
How can I fix this? I know I need to set LastIndex = -1 somewhere but I can't figure it out.
You are right, you can set lastIndex to -1 after you don't find an item:
Code:
If Not (Items is Nothing) Then
...
Else
LastIndex = -1
End If
By the way, this will cause a "skip" in the rotation before it goes back to the beginning. At one point nothing will be highlighted and then it will return to the beginning. You will have to press the button twice to get to go back to the beginning. If that is okay then you can leave it as it is, otherwise, I would recommend changing the way it works. Instead of doing it this way, I would keep a List of ListView items that match the current search and just change the index of the currently shown one in the list. That will allow you to rotate through them without getting a skip. When a new search is done make a new list that matches the search and rotate about that list.
Not exactly... I was thinking that keeping a list of the ListViewItems that match the current search. When it's the same search you can just cycle through that list and highlight accordingly. Something like this:
Code:
Public Class Form
Private lastSearch As String 'the last text the user searched for
Private currentIndex = 0 'the current index to highlight
Private matchingList As List(Of ListViewItem) = New List(Of ListViewItem) ' the list of matching ListViewItems
....
Then make a couple methods; one to fill the list on a new search and the other to highlight the next item in the list
Thank you so Much I tweaked your code to turn it into a Function so I can keep calling it over again for different objects. Thanks again Works like a Charm.
I have 1 List View on 1 Form and another List View on another Form.
So now, if I search for say "A" on the First Form, then try to search "A" on the Second Form it doesn't work.
Here's the code I'm using:
Code:
Public Function FindInList(ByVal ListName As ListView, ByVal SearchText As String) As Boolean
With frmStudents
matchingList.Clear()
Dim listViewItem As ListViewItem
Dim lastIndex As Integer = -1
listViewItem = Nothing
Do Until lastIndex >= ListName.Items.Count - 1
listViewItem = ListName.FindItemWithText(SearchText, True, lastIndex + 1)
If Not (listViewItem Is Nothing) Then
matchingList.Add(listViewItem)
lastIndex = listViewItem.Index
Else
Return Nothing
End If
Loop
End With
End Function
Public Function HighLightInList(ByVal ListName As ListView) As Boolean
If (ListName.SelectedItems.Count > 0) Then
ListName.SelectedItems(0).Selected = False
End If
matchingList(currentIndex).Selected = True
currentIndex = (currentIndex + 1) Mod matchingList.Count
ListName.Focus()
End Function
Public Sub Overview_Assign_Find() 'FORM 1 SEARCH
With frmOverview
Dim searchText As String = .txtAssigmentSearch.Text '.Trim()
If searchText <> lastSearch Then
lastSearch = searchText
currentIndex = 0
FindInList(.lstAssignments, .txtAssigmentSearch.Text)
End If
HighLightInList(.lstAssignments)
End With
End Sub
Public Sub Assign_Find() 'FORM 2 SEARCH
With frmAssignments
Dim searchText As String = .tstSearch.Text '.Trim()
If searchText <> lastSearch Then
lastSearch = searchText
currentIndex = 0
FindInList(.lstAssign, .tstSearch.Text)
End If
HighLightInList(.lstAssign)
End With
End Sub
it compiles? You duplicated everything on the second form that you have on the first? You are not trying to call one form's code from the other are you?
There's no reason that it should not work if you've duplicated everything.
But I search for A on the First and A on the Second, the Second Search for A will not Select. Theirs no Error - its just selecting the ITEM. I did some TEST to check if it trying to change the Correct Listview and it is.
you can attach it here if you like, i'm on my linux machine and don't have an msn client setup yet... Look at the "attach files" section when you are posting... zip up your project and attach the code
frmOverview [The 2 Listviews (Students and Assignments)]
modFindings [All]
frmStudents [The Search Button on the Bottom Right]
frmAssignments [The Search Button on the Bottom Right]
Here is an example. The Find method will get the sub item of the listView control with the specified text:
Code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As ListViewItem.ListViewSubItem = Me.Find(Me.ListView1, "d")
End Sub
Private Function Find(ByVal lv As ListView, ByVal text As String) As ListViewItem.ListViewSubItem
For Each lvi As ListViewItem In lv.Items
For Each lvsi As ListViewItem.ListViewSubItem In lvi.SubItems
If lvsi.Text = text Then
Return lvsi
End If
Next lvsi
Next lvi
Return Nothing
End Function
End Class
Rating is a way of saying thank you. Don't forget to rate always!
Hey wy125, I fixed this issue, I just called a new SUB ClearFindings every time I go to a New Form & I clear the Following:
vb Code:
Public Sub ClearFindings()
lastSearch = vbNullString
currentIndex = 0
matchingList.Clear()
End Sub
ANd it works:
But now heres something that has been bothering me for the longest time. How do I figure out if the text I put into the Text Box is somewhere in the ListView? It was easy with a ListBox I just did a .Contains but I can't figure out for a ListView. This causes my other problem with when no text can be found it gives me a Error with the IndexoutofRange.
So short and simple:
How do I check if the Input Text Is In the ListView?