AutoComplete ComboBox Search on Substring for KeyPress

M

memead

I have a combobox displaying the full name of a customer (e.g. John Smith)
and would like to go to the LAST name whenever a user presses a key while on
this combobox. I have looked at the AutoCompleteMode and AutoCompleteSource
properties of the combobox, but they only key off of the FIRST name (e.g.
pressing "B" will select "Bob Smith", not "Sam Barnes"). Even FindString and
FindStringExact only appear to key off of the prefix. This combobox,
cboCustomer, has a .DataSource set to a DataView (dv) which contains two
fields, the customer's name (e.g. "John Smith") and their customer number
(e.g. 12345). The .ValueMember of this combobox is dv.CustomerNumber and the
..DisplayMember is set to dv.FullName. How can I set the AutoCompleteSource
(?) to be a substring (Last Name) of the .DisplayMember (Full Name)? I
looked at Ken Tucker's response in "Typing in a ComboBox" (04/12/2006) and it
look interesting, but I do not know if this would help me. Any help is
appreciated.

Thank you.
 
K

Kerry Moorman

memead,

Wouldn't it make more sense to display the name in the combobox as Last,
First?

Kerry Moorman
 
L

Lloyd Sheen

memead said:
I have a combobox displaying the full name of a customer (e.g. John Smith)
and would like to go to the LAST name whenever a user presses a key while on
this combobox. I have looked at the AutoCompleteMode and AutoCompleteSource
properties of the combobox, but they only key off of the FIRST name (e.g.
pressing "B" will select "Bob Smith", not "Sam Barnes"). Even FindString and
FindStringExact only appear to key off of the prefix. This combobox,
cboCustomer, has a .DataSource set to a DataView (dv) which contains two
fields, the customer's name (e.g. "John Smith") and their customer number
(e.g. 12345). The .ValueMember of this combobox is dv.CustomerNumber and the
.DisplayMember is set to dv.FullName. How can I set the AutoCompleteSource
(?) to be a substring (Last Name) of the .DisplayMember (Full Name)? I
looked at Ken Tucker's response in "Typing in a ComboBox" (04/12/2006) and it
look interesting, but I do not know if this would help me. Any help is
appreciated.

Thank you.


I have an implementation that uses a text box and a hidden (until
typing) listbox. It will present names on a "contains" basis. I am not
near the box the code is on but will post it tommorow.

LS
 
L

Lloyd Sheen

Lloyd said:
I have an implementation that uses a text box and a hidden (until
typing) listbox. It will present names on a "contains" basis. I am not
near the box the code is on but will post it tommorow.

LS


First you need two controls. The first is a textbox (mine is named
ArtistName. The second is a ListBox (mine is named ArtistNameList.
Place the Listbox immediately under the textbox and make its visibility
=false so that it won't show during normal activities.

Now your first eventhandler is for TextChanged on the textbox. In this
event we will use the current text in the textbox to search (this
depends on where the info is that you are using. I am using LINQ to a
SQL Server database but that is not an issue. The search will return a
list of strings and those strings will be bound to the listbox. If the
count of the list of strings is greater than zero you show the listbox
(it will show right under the text box. You can keep typing and the
list should get smaller as the criteria gets more defined.

There is a bunch of code using add/remove handler which I put in to make
the GUI work. You can play with those to see what happens but this is
fairly old code so I don't remember exactly why they are there but I am
sure it will not work correctly without them.

I use the leave event on the ArtistName with a timer to cause the
ArtistNameList to makes its visible=false after a half second. This
will happen when the any other control gets focus.


Hope this gives you a start and sorry about the code wrapping below:



Private Sub ArtistName_TextChanged(ByVal sender As System.Object, ByVal
e As System.EventArgs) 'Handles ArtistName.TextChanged
Dim s As String = CType(sender, TextBox).Text
Dim q As List(Of String)
q = (From song In linqItems.SongInfos Where song.Artist.Contains(s)
Select song.Artist Distinct Order By Artist).ToList
ArtistNameList.DisplayMember = "toString"
RemoveHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
RemoveHandler ArtistNameList.SelectedIndexChanged, AddressOf
ArtistNameList_SelectedIndexChanged
ArtistNameList.DataSource = q
ArtistNameList.SelectedItems.Clear()
AddHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
AddHandler ArtistNameList.SelectedIndexChanged, AddressOf
ArtistNameList_SelectedIndexChanged
If ArtistNameList.Visible = False And q.Count > 0 Then
ArtistNameList.Visible = True
End If
End Sub




Private Sub ArtistNameList_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) 'Handles
ArtistNameList.SelectedIndexChanged
Dim anl As ListBox = CType(sender, ListBox)
If anl.SelectedIndex = -1 Then
Exit Sub
End If
anl.Visible = False
RemoveHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
ArtistName.Text = anl.SelectedItem.ToString
AddHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
setItems(ArtistName.Text)
End Sub

Private Sub ArtistName_Leave(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ArtistName.Leave
Timer1.Interval = 500
Timer1.Enabled = True
'ArtistNameList.Visible = False
End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Timer1.Enabled = False
ArtistNameList.Visible = False
End Sub
 
M

memead

Thank you. I will see if this works for me.

Lloyd Sheen said:
First you need two controls. The first is a textbox (mine is named
ArtistName. The second is a ListBox (mine is named ArtistNameList.
Place the Listbox immediately under the textbox and make its visibility
=false so that it won't show during normal activities.

Now your first eventhandler is for TextChanged on the textbox. In this
event we will use the current text in the textbox to search (this
depends on where the info is that you are using. I am using LINQ to a
SQL Server database but that is not an issue. The search will return a
list of strings and those strings will be bound to the listbox. If the
count of the list of strings is greater than zero you show the listbox
(it will show right under the text box. You can keep typing and the
list should get smaller as the criteria gets more defined.

There is a bunch of code using add/remove handler which I put in to make
the GUI work. You can play with those to see what happens but this is
fairly old code so I don't remember exactly why they are there but I am
sure it will not work correctly without them.

I use the leave event on the ArtistName with a timer to cause the
ArtistNameList to makes its visible=false after a half second. This
will happen when the any other control gets focus.


Hope this gives you a start and sorry about the code wrapping below:



Private Sub ArtistName_TextChanged(ByVal sender As System.Object, ByVal
e As System.EventArgs) 'Handles ArtistName.TextChanged
Dim s As String = CType(sender, TextBox).Text
Dim q As List(Of String)
q = (From song In linqItems.SongInfos Where song.Artist.Contains(s)
Select song.Artist Distinct Order By Artist).ToList
ArtistNameList.DisplayMember = "toString"
RemoveHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
RemoveHandler ArtistNameList.SelectedIndexChanged, AddressOf
ArtistNameList_SelectedIndexChanged
ArtistNameList.DataSource = q
ArtistNameList.SelectedItems.Clear()
AddHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
AddHandler ArtistNameList.SelectedIndexChanged, AddressOf
ArtistNameList_SelectedIndexChanged
If ArtistNameList.Visible = False And q.Count > 0 Then
ArtistNameList.Visible = True
End If
End Sub




Private Sub ArtistNameList_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) 'Handles
ArtistNameList.SelectedIndexChanged
Dim anl As ListBox = CType(sender, ListBox)
If anl.SelectedIndex = -1 Then
Exit Sub
End If
anl.Visible = False
RemoveHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
ArtistName.Text = anl.SelectedItem.ToString
AddHandler ArtistName.TextChanged, AddressOf ArtistName_TextChanged
setItems(ArtistName.Text)
End Sub

Private Sub ArtistName_Leave(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ArtistName.Leave
Timer1.Interval = 500
Timer1.Enabled = True
'ArtistNameList.Visible = False
End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Timer1.Enabled = False
ArtistNameList.Visible = False
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top