简体   繁体   中英

searching listview in vb.net one-by-one

I am trying to search through items in listview control in vb.net one by one. ie When the user types in some keyworrk in the textbox and presses enter, the first found item in the listview should get highlighted, when he presses enter again, the second search item in the listview should get highlighted and so on.

I am not fully aware of how to keep track of already found items while searching. As of now , I am searching all the items in the listbx using the code :

   If (e.KeyCode = Keys.Enter) Then
                'START


        ListView1.BeginUpdate()
        ListView1.SelectedIndices.Clear()
        If TextBox1.Text.Length > 0 Then
            Dim lstOfStrings() As String = TextBox1.Text.Split(","c)
            For Each s As String In lstOfStrings
                For index As Integer = 0 To ListView1.Items.Count - 1

                    If s.Trim() <> "" Then

                        Dim item As String = ListView1.Items(index).ToString()

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

                            'ListView1.SelectedIndices.Add(index)
                            ListView1.Items(index).BackColor = Color.LightPink
                        End If
                    End If
                Next
            Next s
        End If
        ListView1.EndUpdate()
End if

You have several options, I believe

  1. You can simply add a comparison on the background colour as well.
  2. You can use the item's tag property, if you're not using it already for something, to indicate whether it is highlighted already or not
  3. You can keep the position/value/name of the currently highlighted entry in a globalvariable and refer to it.

As for a sample for #3 - what this means is that you would have a variable, outside the method for example -

Dim highlightedItem as String

In your loop, where you currently change the background colour, you would also set this variable; if, for example, you wanted to use the same value you use for comparison (I assume it's unique), you could use

highlightedItem = item

In your loop you will need to ignore any entry before you reach the currently highlighted item, to do that declare boolean variable highlightedItemFound OUTSIDE the loop and then inside the loop, after extracting item, add something like

If not highlightedItemFound and item=highlightedItem then
       highlightedItemFound = true
       continue
end if 

This will ensure that your check will only start applying after the highlighted item is reached in the list.

You will also need to remove the highlight from the previously selected one, but as you will have a reference to it in the variable you can do it as you loop as well.

This does exactly what you want: Just call FindInListView function when the user press enter, the same function can be used with more than one listview! I added also a "FindInGrid" function it does exactly the same but with DataGrids.

        Private DicPos As New Dictionary(Of Integer, Integer)

    Public Function FindInListView(ByVal lv As ListView, ByVal Texto As String) As Integer

        If Not DicPos.ContainsKey(lv.Handle) Then
            DicPos.Add(lv.Handle, -1)

        End If
        If lv.Items.Count = 0 Then Return 0
        Texto = Texto.Trim.ToUpper
        If Texto.Length = 0 Then lv.Items(0).Selected = True
        Dim Itm As ListViewItem
        For x As Integer = DicPos(lv.Handle) + 1 To lv.Items.Count - 1
            Itm = lv.Items(x)
            For Each cell As ListViewItem.ListViewSubItem In Itm.SubItems
                If cell.Text.ToUpper.Contains(Texto) Then
                    lv.Items(x).Selected = True
                    Try
                        lv.BindingContext.Item(lv.DataBindings).Position = x
                    Catch ex As Exception
                    End Try
                    DicPos(lv.Handle) = Itm.Index
                    Return DicPos(lv.Handle)
                End If
            Next
        Next
        If DicPos(lv.Handle) = -1 Then
            lv.BindingContext.Item(lv.DataBindings).Position = 0
            Return DicPos(lv.Handle)
        Else
            DicPos(lv.Handle) = -1
            Return FindInListView(lv, Texto)
        End If

    End Function

    Public Function FindInGrid(ByVal Grid As DataGridView, ByVal Texto As String, ByVal Position As Integer) As Integer
        Texto = Texto.Trim.ToUpper
        If Texto.Length = 0 Then
            Grid.BindingContext.Item(Grid.DataSource).Position = 0
            Return 0
        End If
        For x As Integer = Position To Grid.Rows.Count - 1
            For Each Cel As DataGridViewCell In Grid.Rows(x).Cells
                If Cel.Value.ToString.ToUpper.Contains(Texto) Then
                    Grid.Rows(Cel.RowIndex).Selected = True
                    Try
                        Grid.BindingContext.Item(Grid.DataSource).Position = x
                    Catch ex As Exception

                    End Try
                    Return Cel.RowIndex
                End If
            Next
        Next
        If Position = 0 Then
            Grid.BindingContext.Item(Grid.DataSource).Position = 0
            Return 0
        Else
            Return FindInGrid(Grid, Texto, 0)
        End If
    End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM