bradwebber
asked on
Custom ComboBox Problem
I am trying to create a custom ComboBox control. I have inherited from the standard ComboBox control. When the user types something into my custom ComboBox I want the ComboBox to drop down the item list. To do this I have simply placed the following line in the KeyUp event of my custom ComboBox:
me.DroppedDown = True
The item list drops down as expected, but the problem is that the cursor then disappears. I have to press the Escape key or click the mouse button to make the cursor reappear, but the item list then retracts.
How can I drop down the item list without having the mouse cursor disappear?
(I am using VB.NET and VS2003)
me.DroppedDown = True
The item list drops down as expected, but the problem is that the cursor then disappears. I have to press the Escape key or click the mouse button to make the cursor reappear, but the item list then retracts.
How can I drop down the item list without having the mouse cursor disappear?
(I am using VB.NET and VS2003)
what are u trying to achieve exactly? an auto-suggest
ASKER
Yeah, pretty much. What I am wanting to do is create a dynamic ComboBox that displays a list of matching items in it's item list (rather than displaying all items and simply selecting the first match).
If the ComboBox contains a match to the user input, the ComboBox will drop down its item list and the user can select the appropriate item.
If the ComboBox contains a match to the user input, the ComboBox will drop down its item list and the user can select the appropriate item.
Well... im not sure it's possible to type into a combo box and have the dropdown visible as well... i could be wrong... you could do it so you type in there, then when you click the drop down, it shows items which are like the text entered.
if you know some where which has a similar control (used in some windows program, point it out so i know what it is like)
assuming that its not possible to have the drop down visible and have the user type... you could use a textbox, a dropdown button, and a listbox... prolly won't look as pretty but might be an easy workaround
if you know some where which has a similar control (used in some windows program, point it out so i know what it is like)
assuming that its not possible to have the drop down visible and have the user type... you could use a textbox, a dropdown button, and a listbox... prolly won't look as pretty but might be an easy workaround
ASKER
I can type into the ComboBox when the the dropdown is visible, it is just that the cursor is invisible when I do this. It turns out to be a big problem because the user can't select any of the items in the dropdown (because they can't see the cursor).
I was thinking of building my own from scratch (i.e. not inheriting from ComboBox) but I don't know how to paint the dropdown portion of the control. How can the standard ComboBox control paint its dropdown area when the actual height of the control is considerably smaller?
I was thinking of building my own from scratch (i.e. not inheriting from ComboBox) but I don't know how to paint the dropdown portion of the control. How can the standard ComboBox control paint its dropdown area when the actual height of the control is considerably smaller?
im guessing the dropdown part is a seperate window created by the control itself...
and sorry, i slightly misunderstood your meaning of cursor... lots of people on here confuse the cursor with the caret and I just assumed you meant caret... I just tried what you're doing any have noticed that the cursor is invisible when within the bounds of the form (when the droplist is down and your typing). I'll see if i can tweak it somehow to keep it visible
and sorry, i slightly misunderstood your meaning of cursor... lots of people on here confuse the cursor with the caret and I just assumed you meant caret... I just tried what you're doing any have noticed that the cursor is invisible when within the bounds of the form (when the droplist is down and your typing). I'll see if i can tweak it somehow to keep it visible
ASKER
That would be great. If it could be kept visible then what I need to to is fairly simple.
Cheers.
Cheers.
weird... not sure what difference you have but when i push Esc... the list retracts, then reappears (because of the Esc keyup event), but the mouse is then visible... which suggests that it's possible for a cursor to be above the dropdown and still be typing
ASKER
Sorry, you are right. I had some additional code in the keyup event. Yep, when I press the escape key now the dropdown reappears and the cursor remains on screen.
I have tried using SendKeys.Send("ESC}") in the keyup event to simulate pressing the escape key, but I couldn't get it to work properly.
I have tried using SendKeys.Send("ESC}") in the keyup event to simulate pressing the escape key, but I couldn't get it to work properly.
I've tried using the keybd_event and had no luck with that either....
when you put a combobox at the bottom of the form and pull down the list, it goes past the bounds of the form which gives you the impression the dropdown part is it's own window... I suppose if you were to design your own, you could have a borderless form, with a listbox and use that as the dropdown list... and then the combobox is just textbox with a button for pulling down the list... and when that's click, the borderless form is lined up to the combo box and then shown... clicking on an item i nthe list sets the textbox and hides the form... but also taking the focus away from the form closes it
when you put a combobox at the bottom of the form and pull down the list, it goes past the bounds of the form which gives you the impression the dropdown part is it's own window... I suppose if you were to design your own, you could have a borderless form, with a listbox and use that as the dropdown list... and then the combobox is just textbox with a button for pulling down the list... and when that's click, the borderless form is lined up to the combo box and then shown... clicking on an item i nthe list sets the textbox and hides the form... but also taking the focus away from the form closes it
Here's a customized auto-complete combobox class, I've used it a lot and it works very well:
Option Strict On
Option Explicit On
Imports System.Windows.Forms
Public Class AutoCompleteCombo
Inherits ComboBox
Private mResetOnClear As Boolean = False
Protected Overrides Sub RefreshItem(ByVal index As Integer)
MyBase.RefreshItem(index)
End Sub
Protected Overrides Sub SetItemsCore(ByVal items As System.Collections.IList)
MyBase.SetItemsCore(items)
End Sub
Public Shadows Sub KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr essEventAr gs) Handles MyBase.KeyPress
Dim intIndex As Integer
Dim strEntry As String
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
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.Key Char)) And (Not Char.IsWhiteSpace(e.KeyCha r)) 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
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
Option Strict On
Option Explicit On
Imports System.Windows.Forms
Public Class AutoCompleteCombo
Inherits ComboBox
Private mResetOnClear As Boolean = False
Protected Overrides Sub RefreshItem(ByVal index As Integer)
MyBase.RefreshItem(index)
End Sub
Protected Overrides Sub SetItemsCore(ByVal items As System.Collections.IList)
MyBase.SetItemsCore(items)
End Sub
Public Shadows Sub KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPr
Dim intIndex As Integer
Dim strEntry As String
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
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.Key
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
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
ASKER
Hi amyhxu,
What I really need my combo box to do is to automatically display the dropdown when the user starts typing (and there is a matching entry in the list). The autocomplete functionality that you have provided is great, but I won't be able to use it effectively unless I can also automatically display the dropdown.
What I really need my combo box to do is to automatically display the dropdown when the user starts typing (and there is a matching entry in the list). The autocomplete functionality that you have provided is great, but I won't be able to use it effectively unless I can also automatically display the dropdown.
I did some test using autocomplete combobox with the auto dropdown display, and it worked.
Private WithEvents cb As AutoCompleteCombo
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Fill myTable first
cb = New AutoCompleteCombo
Me.Controls.Add(cb)
cb.Location = New Point(100, 100)
cb.DataSource = myTable
cb.DisplayMember = "Col1"
cb.ValueMember = "Col2"
cb.SelectedIndex = -1
End Sub
Private Sub cb_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEv entArgs) Handles cb.KeyDown
cb.DroppedDown = True
End Sub
Private WithEvents cb As AutoCompleteCombo
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Fill myTable first
cb = New AutoCompleteCombo
Me.Controls.Add(cb)
cb.Location = New Point(100, 100)
cb.DataSource = myTable
cb.DisplayMember = "Col1"
cb.ValueMember = "Col2"
cb.SelectedIndex = -1
End Sub
Private Sub cb_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEv
cb.DroppedDown = True
End Sub
ASKER
Hi there amyhxu, thanks for your reply.
What I would like to be able to do is to encapsulate the cb.DroppedDown = True into the custom control, rather than having to put it on the form that contains the control. I have not been able to get it to work though when I attempt to do this.
Sorry for being so picky! :)
What I would like to be able to do is to encapsulate the cb.DroppedDown = True into the custom control, rather than having to put it on the form that contains the control. I have not been able to get it to work though when I attempt to do this.
Sorry for being so picky! :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi there Amyhxu,
Thank you very much for your solution!
Thank you very much for your solution!