Winformscombobox在lostfocus上失去自动完成值

当用户选中下一个控件时,我遇到Winformscombobox丢失在自动完成期间找到的值的问题。

这是一个代码示例(作为将弹出表单的Nunit测试):

[Test] [STAThread] public void Testing_AsDropDownList() { var comboBox = new ComboBox(); comboBox.DropDownStyle = ComboBoxStyle.DropDownList; comboBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; comboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; comboBox.Items.Add(new ComboPair("aaa", "ItemAAA")); comboBox.Items.Add(new ComboPair("bbb1", "ItemBBB1")); comboBox.Items.Add(new ComboPair("bbb2", "ItemBBB2")); comboBox.Items.Add(new ComboPair("bbb3", "ItemBBB3")); comboBox.Items.Add(new ComboPair("ccc", "ItemCCC")); var textBox = new TextBox{ Multiline = true }; comboBox.Leave += (sender, args) => textBox.Text = "On Leave: " + comboBox.SelectedItem; comboBox.LostFocus += (sender, args) => textBox.Text += " ... On LostFocus: " + comboBox.SelectedItem; var frm = new Form(); frm.Width = 300; frm.Height = 100; comboBox.Dock = System.Windows.Forms.DockStyle.Top; textBox.Dock = System.Windows.Forms.DockStyle.Bottom; frm.Controls.Add(comboBox); frm.Controls.Add(textBox); Application.EnableVisualStyles(); Application.Run(frm); } 

要重现该错误,请执行以下步骤:

  1. 运行测试表单将弹出combobox聚焦…
  2. 现在输入’bbb3’以选择具有自动完成function的相应项目。 现在,您将看到文本框已更新为“bbb3”作为您选择的项目。
  3. 现在按TAB键

您现在将看到文本框具有焦点,并且组合选择已更改为“bbb1”。 另请注意,在文本框中,它会向您显示在触发离开事件时所选值仍为“bbb3”,但在失去焦点事件触发时为“bbb1”。

如果您单击combobox以使其在步骤3中失去焦点,则会出现相同的行为。

如果您在步骤3中执行任何其他操作,则不会出现此问题。 即如果你:

  • 按’输入’
  • 按“向上”然后“向下”回到“bbb3”
  • 单击该项目
  • 等等

有任何想法吗?

我从微软发现了这个链接

http://connect.microsoft.com/VisualStudio/feedback/details/711945/tab-on-a-winforms-combobox-with-properties-autocompletemode-append-autocompletesource-listitems-doesnt-work-correctly

基本上这是一个已知的问题,微软表示他们无法解决。 但是,该链接的变通方法部分有两种解决方法。

该值在WM_KILLFOCUS消息中丢失。 在ComboBox的子类中覆盖WndProc为我解决了这个问题(除了点击松散焦点…但我想这可以解释为像在网站对话框上那样解雇)。 不幸的是,我手边只有VB.NET代码:

 Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H8 Then 'WM_KILLFOCUS Dim sText As String = Me.Text MyBase.WndProc(m) Me.Text = sText Exit Sub End If MyBase.WndProc(m) End Sub