Link to home
Start Free TrialLog in
Avatar of mah8473
mah8473

asked on

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
ASKER CERTIFIED SOLUTION
Avatar of Sancler
Sancler

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Howard Cantrell


This is what you need...

Public Class frmComboTypeHead
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call
        InitializeCombobox()
    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
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    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.SuspendLayout()
        '
        'ComboBox1
        '
        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
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 269)
        Me.Controls.Add(Me.ComboBox1)
        Me.Name = "frmComboTypeHead"
        Me.Text = "frmComboTypeHead"
        Me.ResumeLayout(False)

    End Sub
#End Region
    Private Sub InitializeCombobox()
        With ComboBox1
            .Items.Clear()
            .Items.Add(UCase("one"))
            .Items.Add("two")
            .Items.Add("other")
            .Items.Add("new")
            .Items.Add("newer")
            .Items.Add("newbee")
            .Items.Add("safe")
            .Items.Add("error")
            .Items.Add("apple")
            .Items.Add("alter")
            .Items.Add("ables")
            .Items.Add("absents")
        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

        'or

        '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
                Return
        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
Avatar of mah8473
mah8473

ASKER

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
Avatar of mah8473

ASKER

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