VB 2005 - Filter List Box

Soldato
Joined
21 Jul 2004
Posts
6,360
Location
Harrow, UK
I have a list box populated with data from a directory listing (file names), and now I want to add a search box that will filter this list after every typed letter.

Does anyone know how to do this?
 
Code:
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        If TextBox1.Text.Trim.Length > 0 Then
            ListBox1.SelectedIndex = ListBox1.Items.IndexOf(TextBox1.Text.Trim.ToUpper)
        Else
            ListBox1.SelectedIndex = -1
        End If
End Sub
 
Code:
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        If TextBox1.Text.Trim.Length > 0 Then
            ListBox1.SelectedIndex = ListBox1.Items.IndexOf(TextBox1.Text.Trim.ToUpper)
        Else
            ListBox1.SelectedIndex = -1
        End If
End Sub

I just tried that and it does nothing :(
 
He was close!
The IndexOf will find the location when then whole string matches. So if your list was 1,2,3 it would match "1" or "2" or "3" typed.

Try
Code:
    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        If TextBox1.Text.Trim.Length > 0 Then
            ListBox1.SelectedIndex = ListBox1.FindString(TextBox1.Text.Trim.ToUpper)
        Else
            ListBox1.SelectedIndex = -1
        End If
    End Sub

Doesn't exactly filter the list, more highlight the first instance of text that matches the current string.
What you'd have to do to get a proper filter is do a dataview of the dataset that is bound to the list. you can then sort/filter that and rebind the listbox.

You could also do something like:
Have a second hidden listbox which contains the full list.
Clear the items from then displayed listbox,
Loop through the items in the hidden one, if text matches then add the item to the visible listbox.



Simon
 
Last edited:
This little control might give you some ideas its a auto completing combo box

Code:
Option Strict On
Option Explicit On

Imports System.Windows.Forms
Public Class AutoCompleteCombo
    Inherits ComboBox
    Private _numeric As Boolean
    Private mResetOnClear As Boolean = False

    Protected Overrides Sub RefreshItem(ByVal index As Integer)
        MyBase.RefreshItem(index)
    End Sub

    Public Property ItemIndex() As Integer
        Get
            Return MyBase.SelectedIndex
        End Get
        Set(ByVal value As Integer)
            MyBase.SelectedIndex = value
        End Set
    End Property
    Protected Overrides Sub SetItemsCore(ByVal items As System.Collections.IList)
        MyBase.SetItemsCore(items)
    End Sub
    Public Property Numeric() As Boolean
        Get
            Return _numeric
        End Get
        Set(ByVal value As Boolean)
            _numeric = value
        End Set
    End Property

    Dim _ro As Boolean

    Public Property Read_Only() As Boolean
        Get
            Return _ro
            

        End Get
        Set(ByVal value As Boolean)

            _ro = value
            If value Then
                MyBase.BackColor = SystemColors.Control
                MyBase.Enabled = False

            Else
                MyBase.BackColor = SystemColors.Window
                MyBase.Enabled = True

            End If


        End Set
    End Property




    Public Shadows Sub KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress
        Dim intIndex As Integer
        Dim strEntry As String
        If Numeric Then
            If Not IsNumeric(e.KeyChar) Then
                If MyBase.Text.Length > 0 Then
                    'MyBase.Text = MyBase.Text.Substring(1, MyBase.Text.Length - 1)
                    MyBase.SelectionStart = MyBase.Text.Length
                End If
                e.Handled = True
                Exit Sub
            End If
        End If
        If Char.IsControl(e.KeyChar) Then
            If MyBase.SelectionStart <= 1 Then
                If mResetOnClear Then
                    MyBase.SelectedIndex = 0
                    MyBase.SelectAll()
                Else
                    MyBase.Text = String.Empty
                    MyBase.SelectedIndex = -1
                End If
                e.Handled = True
                Exit Sub
            End If
            If MyBase.SelectionLength = 0 Then
                strEntry = MyBase.Text.Substring(0, MyBase.Text.Length - 1)
            Else
                strEntry = MyBase.Text.Substring(0, MyBase.SelectionStart - 1)
            End If
        ElseIf (Not Char.IsLetterOrDigit(e.KeyChar)) And (Not Char.IsWhiteSpace(e.KeyChar)) Then  '< 32 Or KeyAscii > 127 Then
            Exit Sub
        Else
            If MyBase.SelectionLength = 0 Then
                strEntry = UCase(MyBase.Text & e.KeyChar)
            Else
                strEntry = MyBase.Text.Substring(0, MyBase.SelectionStart) & e.KeyChar
            End If
        End If

        intIndex = MyBase.FindString(strEntry)

        If intIndex <> -1 Then
            MyBase.SelectedIndex = intIndex
            MyBase.SelectionStart = strEntry.Length
            MyBase.SelectionLength = MyBase.Text.Length - MyBase.SelectionStart
        Else
            MyBase.SelectedIndex = -1
            MyBase.Text = strEntry
            MyBase.SelectionStart = strEntry.Length
        End If
        e.Handled = True
        Exit Sub
    End Sub

    Public Property ResetOnClear() As Boolean
        Get
            Return mResetOnClear
        End Get
        Set(ByVal Value As Boolean)
            mResetOnClear = Value
        End Set
    End Property
End Class
 
Back
Top Bottom