Try turning AutoCompleteMode to become SuggestAppend, and AutoCompleteSource to become ListItems. Then you can remove the entire TextChanged code block and it should also work properly on XP.
ComboBox.SelectedValue getting reset in Windows XP only
-
13-06-2023 - |
Question
I'm having some issues with WinForms ComboBox
class. What I am trying to achieve is programmatically setting SelectedValue
from the ComboBox.TextChanged
handler once a match is found. This works fine on Windows 7, but in Windows XP SelectedValue
will get set and SelectedValueChanged
will be raised, but then once it reaches Validating
SelectedValue
returns Nothing
. It seems the only way to change SelectedValue
in XP is via selecting something from the dropdown.
Here's a toy Form
with just a ComboBox
and a multi-line TextBox
.
XP: Typed into the ComboBox
is 1Y, then tab is pressed. Output:
SelectedValueChanged: SelectedValue: 1X
Validating: SelectedValue: Nothing
Value is:
Validated: SelectedValue: Nothing
Win7: Typed into the ComboBox
is 1Y, then tab is pressed. Output:
SelectedValueChanged: SelectedValue: 1X
Validating: SelectedValue: 1X
Value is: 1X
Validated: SelectedValue: 1X
Code:
Public Class ComboBoxXPForm
Private WithEvents mData As New DataHolder
Private mBindingSrc As BindingSource
Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
mBindingSrc = New BindingSource() With {.DataSource = mData}
Dim dt As New DataTable()
dt.Columns.Add("value", GetType(String))
dt.Columns.Add("displayValue", GetType(String))
dt.Rows.Add("", "")
For i = 1 To 10
dt.Rows.Add(i & "X", i & "Y")
Next
cboBox.DataSource = dt
cboBox.ValueMember = "value"
cboBox.DisplayMember = "displayValue"
cboBox.DataBindings.Add("SelectedValue", mBindingSrc, "StrVal", True)
End Sub
Private Sub cboBox_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.SelectedValueChanged
txtDebug.Text &= vbNewLine & "SelectedValueChanged: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
Private Sub DataHolder_DebugInfo(ByVal sender As Object, ByVal e As DebugEventArgs) Handles mData.DebugInfo
txtDebug.Text &= vbNewLine & e.DebugInfo
End Sub
Private Sub cboBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.TextChanged
'For Each row In cboBox.Items
' If cboBox.Text = row("displayValue") AndAlso row("value") <> cboBox.SelectedValue Then
' 'cboBox.SelectedValue = row("value")
' cboBox.SelectedItem = row
' End If
'Next
For i = 0 To cboBox.Items.Count - 1
Dim item = cboBox.Items(i)
If cboBox.Text = item("displayValue") Then
cboBox.SelectedIndex = i
End If
Next
End Sub
Private Sub cboBox_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboBox.Validated
txtDebug.Text &= vbNewLine & "Validated: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
Private Sub cboBox_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cboBox.Validating
txtDebug.Text &= vbNewLine & "Validating: SelectedValue: " & _
If(cboBox.SelectedValue Is Nothing, _
"Nothing", cboBox.SelectedValue.ToString())
End Sub
End Class
Public Class DebugEventArgs
Inherits EventArgs
Private mDebugInfo As String
Public Sub New(ByVal DebugString As String)
MyBase.New()
DebugInfo = DebugString
End Sub
Public Property DebugInfo() As String
Get
Return mDebugInfo
End Get
Set(ByVal value As String)
mDebugInfo = value
End Set
End Property
End Class
Public Class DataHolder
Public Event DebugInfo(ByVal sender As Object, ByVal e As DebugEventArgs)
Private mStrVal As String
Public Property StrVal() As String
Get
Return mStrVal
End Get
Set(ByVal value As String)
mStrVal = value
RaiseEvent DebugInfo(Me, New DebugEventArgs("Value is: " & value))
End Set
End Property
End Class
La solution
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow