Custom ComboBox Problems

R

ross kerr

Hi All,

I am extending the combobox to create a control that
selects an item based on the text the user is typing into
the text area of the control.

I have an issue that occurs only when i drop down the
combo box as the users typing.

When the on leave event is fired the value in the selected
index is correct, but if i check the value after that it
is set to the previous value. if i select item one, the
value is -1, if i then select item 3 the value is 1. If i
remove the code to drop down the list the value is correct.

It sounds similar to a problem mark was having on Jan 7th,
only this doesn't involve data binding.

Any help would be much appreciated.

Thanks,

ross (rkerratbaileyind.com)

Code to follow:

Here is the code for the custom combobox.

Public Class SelectingComboBox
Inherits System.Windows.Forms.ComboBox

Public LimitToList As Boolean = True

#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

End Sub

'UserControl1 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

Protected Overloads Overrides Sub OnKeyPress(ByVal
evt As Windows.Forms.KeyPressEventArgs)
If (evt.KeyChar.ToString = Chr
(Windows.Forms.Keys.Back) _
Or evt.KeyChar.ToString < Chr(32) _
Or evt.KeyChar.ToString > Chr(127)) Then
MyBase.OnKeyPress(evt)
Exit Sub
End If

Me.DroppedDown = True
Dim oldText, newText As String
oldText = Me.Text.Substring(0,
Me.SelectionStart)

If (evt.KeyChar.ToString = Chr(8)) Then
Try
Me.Text = oldText.Substring
(0, oldText.Length - 1)

Catch e2 As System.Exception
Me.Text = ""
Me.SelectedIndex = -1
Exit Sub
End Try

If (Me.Text.Length = 0) Then
Me.SelectedIndex = -1
Exit Sub
End If

newText = Me.Text
Me.SelectedIndex = -1
Me.Text = newText

Me.SelectedIndex = Me.FindString
(Me.Text, 0)
Me.SelectionStart =
oldText.Length - 1
Else
If ((Me.LimitToList = True) And
(Me.FindString(oldText + evt.KeyChar.ToString(), 0) = -1))
Then
evt.Handled = True
Exit Sub
End If

Me.Text = oldText +
evt.KeyChar.ToString()

newText = Me.Text
Me.SelectedIndex = -1
Me.Text = newText

Me.SelectedIndex = Me.FindString
(Me.Text, 0)
Me.SelectionStart = oldText.Length
+ 1

End If

If (Me.Text.Length > Me.SelectionStart)
Then
Me.SelectionLength =
(Me.Text.Length - Me.SelectionStart)
End If

evt.Handled = True

End Sub

Protected Overloads Overrides Sub onleave(ByVal
evt As System.EventArgs)
MyBase.onleave(evt)
Me.Refresh()
End Sub

Protected Overloads Overrides Sub
onSelectedIndexChanged(ByVal evt As System.EventArgs)
MyBase.onSelectedIndexChanged(evt)
System.Console.WriteLine("Selected
Index: " & Me.SelectedIndex)
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.
<System.Diagnostics.DebuggerStepThrough()> Private
Sub InitializeComponent()
components = New
System.ComponentModel.Container
End Sub

#End Region

End Class

Here is the code for the test form. It has a text field,
a button and the custom combobox component.

Public Class Form1
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

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 SelectableComboBox1 As
VBSelectingComboBox.SelectingComboBox
Friend WithEvents Label1 As
System.Windows.Forms.Label
Friend WithEvents TextBox1 As
System.Windows.Forms.TextBox
Friend WithEvents Button1 As
System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private
Sub InitializeComponent()
Me.SelectableComboBox1 = New
VBSelectingComboBox.SelectingComboBox
Me.Label1 = New System.Windows.Forms.Label
Me.TextBox1 = New
System.Windows.Forms.TextBox
Me.Button1 = New
System.Windows.Forms.Button
Me.SuspendLayout()
'
'SelectableComboBox1
'
Me.SelectableComboBox1.Items.AddRange(New
Object()
{"Apple", "Bananna", "Honeydew", "Lemon", "Melon", "Orange"
, "Pineapple", "Pineberries", "Pinenuts", "Strawberries"})
Me.SelectableComboBox1.Location = New
System.Drawing.Point(120, 40)
Me.SelectableComboBox1.Name
= "SelectableComboBox1"
Me.SelectableComboBox1.Size = New
System.Drawing.Size(121, 21)
Me.SelectableComboBox1.TabIndex = 0
'
'Label1
'
Me.Label1.Location = New
System.Drawing.Point(16, 40)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size
(88, 16)
Me.Label1.TabIndex = 1
Me.Label1.Text = "Test ComboBox:"
'
'TextBox1
'
Me.TextBox1.Location = New
System.Drawing.Point(88, 160)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size
(104, 20)
Me.TextBox1.TabIndex = 2
Me.TextBox1.Text = ""
'
'Button1
'
Me.Button1.Location = New
System.Drawing.Point(104, 112)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 3
Me.Button1.Text = "Button1"
'
'Form1
'
Me.AutoScaleBaseSize = New
System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size
(272, 189)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.SelectableComboBox1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region
Dim i As Short
Private Sub
SelectableComboBox1_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
SelectableComboBox1.SelectedIndexChanged
i += 1
Me.Text = "changed " & i & " times.
selected index = " & Me.SelectableComboBox1.SelectedIndex
End Sub

Private Sub ComboLeave(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
SelectableComboBox1.Leave
Me.TextBox1.Text =
Me.SelectableComboBox1.SelectedIndex
End Sub

Private Sub ButtonClick(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
Me.TextBox1.Text =
Me.SelectableComboBox1.SelectedIndex
End Sub
Private Sub getKeyPress(ByVal sender As Object,
ByVal e As Windows.Forms.KeyPressEventArgs) Handles
Button1.KeyPress, SelectableComboBox1.KeyPress,
TextBox1.KeyPress
If Asc(e.KeyChar) =
System.Windows.Forms.Keys.Return Then
SelectNextControl(sender, True,
True, True, True)
e.Handled = True
End If
End Sub
End Class
 
R

ross kerr

Hi Ken,

if i add the code,

Me.DroppedDown = True

to the keypress event in this component i get the same
undesireable behavior.

ross
 
R

ross

Not exactly what i was looking for. Half the time
pressing 'A' will get you Apple with the cursor at the end
of the word and half the time it will select 'Apple' with
a selection and the cursor before the 1st 'p' (what i
would expect).

Looks like it is also be providing the previous
selectedIndex when the list drops down which has been my
problem.

thx,

ross
 
R

ross

I worked around the initial problem by setting a public
variable in the leave and selectedindexchanged events
which i can access instead of selectedindex.

I am still having the same problem that the leave event is
not firing if the user clicks off the combobox while the
dropdown list is displayed.

Any help would be greatly appreciated!
 

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