2014-03-12 16 views
0

我遇到的WinForms ComboBox类的一些问题。我试图实现的是一旦找到匹配,就以编程方式从ComboBox.TextChanged处理程序中设置SelectedValue。这工作正常的Windows 7,但在Windows XP SelectedValue将设置和SelectedValueChanged将提高,但随后一旦达到ValidatingSelectedValue回报Nothing。似乎在XP中更改SelectedValue的唯一方法是通过从下拉列表中选择一些内容。ComboBox.SelectedValue获得重置在Windows XP只

这是玩具Form只有一个ComboBox和一个多行TextBox

XP:键入到ComboBox是1Y,然后标签被按下。输出:

SelectedValueChanged: SelectedValue: 1X 
Validating: SelectedValue: Nothing 
Value is: 
Validated: SelectedValue: Nothing 

Win7的:键入到ComboBox是1Y,然后标签被按压。输出:

SelectedValueChanged: SelectedValue: 1X 
Validating: SelectedValue: 1X 
Value is: 1X 
Validated: SelectedValue: 1X 

代码:

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 
+0

这是一个猜测,但似乎这个问题是改变'.SelectedValue'内'.TextChanged'可能创建一个循环(包括触发对方来回)。如果在“验证”中设置了“.SelectedValue”,那么在Windows XP中不会引发任何问题。 –

回答

1

尝试打开AutoCompleteMode成为SuggestAppend,并AutoCompleteSource成为listItems中。然后你可以删除整个TextChanged代码块,它也应该在XP上正常工作。

+1

这使我朝着正确的方向发展 - 使用'AutoComplete'设置'SelectedValue'而无需手动执行。尽管我最终使用了'Suggest',因为SuggestAppend将'.Text'属性更改为第一个匹配项,如果您想在触发某些行为之前等待匹配项,则不起作用。 –