• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6184
  • Last Modified:

set VB.NET ListBox.selected index as you type into it

Using VB.NET 2.0, how do you select a listbox item as you type into it? This was default behaviour in VB6.0 but I can't seem to make it work in VB.Net. I have found some samples that allow you to set the listbox selectedindex as you type into a textbox but I want to allow the user to type into a listbox and select the relevant item (or nearest match) as they type.

Is this possible?

I first thought it may have something to do with the IMEMode property but can't seem to make it work
  • 2
1 Solution
You cannot "type into" a ListBox.  If you press a key while the listbox has focus the default behaviour is that the selection will move to the next item that starts with the character represented by that single key.

If you want to go further than that you need a ComboBox.  Then you can adjust its .DropDownStyle, and various .AutoComplete... properties to get the precise effect/s that you want.


This is what you need...

Public Class frmComboTypeHead
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()

        'This call is required by the Windows Form Designer.

        'Add any initialization after the InitializeComponent() call
    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
            End If
        End If
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.ComboBox1 = New System.Windows.Forms.ComboBox
        Me.ComboBox1.Location = New System.Drawing.Point(60, 44)
        Me.ComboBox1.MaxLength = 6
        Me.ComboBox1.Name = "ComboBox1"
        Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
        Me.ComboBox1.TabIndex = 0
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 269)
        Me.Name = "frmComboTypeHead"
        Me.Text = "frmComboTypeHead"

    End Sub
#End Region
    Private Sub InitializeCombobox()
        With ComboBox1
        End With
    End Sub
    Private Declare Ansi Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal ptr As IntPtr, ByVal cmd As Integer, ByVal lparam As Int32, ByVal wparam As Integer) As Integer

    Private Sub ComboBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.MouseEnter
        Const CB_SHOWDROPDOWN = &H14F
        Dim iret As Integer
        iret = SendMessage(ComboBox1.Handle, CB_SHOWDROPDOWN, System.Convert.ToInt32(True), 0)
    End Sub

    Private Sub ComboBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.MouseLeave
        Const CB_SHOWDROPDOWN = &H14F
        Dim iret As Integer
        iret = SendMessage(ComboBox1.Handle, CB_SHOWDROPDOWN, System.Convert.ToInt32(False), 0)
    End Sub
    'cbo is the comboBox control
    Private Sub cbo_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp
        AutoCompleteCombo_KeyUp(sender, e)
    End Sub
    Public Shared Sub AutoCompleteCombo_KeyUp(ByVal cbo As ComboBox, ByVal e As KeyEventArgs)
        ' you can use it 2 ways.

        'either add the handles keyword after the sub name to handle your KeyUp event
        'eg. Public Shared Sub AutoCompleteCombo_KeyUp(ByVal cbo As ComboBox, ByVal e As KeyEventArgs) Handles cboSuburb.KeyUp


        'i use it as a generic sub so call it from the KeyUp event as follows:

        '  Private Sub cboSuburb_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles cboSuburb.KeyUp
        '            AutoCompleteCombo_KeyUp(sender, e)
        '        End Sub
        Dim sTypedText As String
        Dim iFoundIndex As Integer
        Dim oFoundItem As Object
        Dim sFoundText As String
        Dim sAppendText As String

        'Allow select keys without Autocompleting
        Select Case e.KeyCode
            Case Keys.Back, Keys.Left, Keys.Right, Keys.Up, Keys.Delete, Keys.Down
        End Select

        'Get the Typed Text and Find it in the list
        sTypedText = cbo.Text
        iFoundIndex = cbo.FindString(sTypedText)

        'If we found the Typed Text in the list then Autocomplete
        If iFoundIndex >= 0 Then

            'Get the Item from the list (Return Type depends if Datasource was bound
            ' or List Created)
            oFoundItem = cbo.Items(iFoundIndex)

            'Use the ListControl.GetItemText to resolve the Name in case the Combo
            ' was Data bound
            sFoundText = cbo.GetItemText(oFoundItem)

            'Append then found text to the typed text to preserve case
            sAppendText = sFoundText.Substring(sTypedText.Length)
            cbo.Text = sTypedText & sAppendText

            'Select the Appended Text
            cbo.SelectionStart = sTypedText.Length
            cbo.SelectionLength = sAppendText.Length

        End If
    End Sub
End Class
mah8473Author Commented:
Sancler thanx for you response.....I just realized that I was actually using a ListView control in VB6.0 NOT a ListBox so the behaviour I was expecting obviously wasn't going to work....DOH!

Probably should've paid closer attention there...oops
mah8473Author Commented:
I was actually trying to add a custom object to the listbox item using a specific Object Property as the ListBox display member....this won't work with a ListView control so I've had to change my approach and am now utilising a textbox for free text typing and selecting the listbox item based on the text entered...or the closest match if there is something similar

Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
        Dim index As Integer = lstListBox.FindString(txtSearch.Text)
        If index <> -1 Then
            lstListBox.SetSelected(index, True)
            lstListBox.TopIndex = index
        End If
End Sub
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now