我有一个继承表单 Forms.ComboBox 类的自定义 ComboBox。它的 DataSource 是绑定的。其属性初始化如下:
this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.DropDownStyle = ComboBoxStyle.DropDown;
OnDropDown 将其 AutoCompleteMode 设置为 None,然后在 OnDropDownClosed 中再次设置为 Suggest(避免出现此处描述的问题WinForms ComboBox DropDown 和 Autocomplete 窗口都出现)
我实现了一个逻辑,它验证 ComboBox 并在键入某些文本时选择第一个匹配项。
当显示 DropDown 并且用户键入内容并按 Enter 时,将选择第一个匹配项。然后我想关闭 DropDown。我通过将 ComboBox.DroppedDown 属性设置为 false 来做到这一点。问题是当 DropDown 以这种方式关闭时,选定的项目会重置为先前选定的项目。不调用 OnSelectedIndexChanged、OnSelectionChangeCommitted 和 OnSelectedValueChanged。
我通过记住在 OnSelectedIndexChanged 中选择的索引并在 OnDropDownClosed 中再次设置它来处理它(在手动关闭 DropDown 的条件下)。
问题: 为什么当 ComboBox 的 DroppedDown 属性设置为 false 时,所选项目、索引、文本和值会重置?还有另一种没有这种副作用的手动关闭组合框的方法吗?
编辑:说明问题的代码:
List<string> list = new List<string>();
list.Add("item0");
list.Add("item1");
list.Add("item2");
list.Add("item3");
list.Add("item4");
customComboBox1.DataSource = list;
...
public class CustomComboBox : ComboBox
{
public CustomComboBox(){ }
#region OnKeyDown
protected override void OnKeyDown(KeyEventArgs e)
{
if (!this.Enabled) e.Handled = true;
else
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Enter)
{
this.SelectedIndex = 2; // index changes here
Console.WriteLine("ENTER - before DroppedDown=false " +
this.SelectedIndex + " " + this.Text);
if (this.DroppedDown)
{
// here index = 2, text = Item2
this.DroppedDown = false;
// here index = previous index, text is still Item2
// different thing is displayed than is actually chosen
// OnSelectedIndexChanged wasn't raised
}
Console.WriteLine("ENTER - after DroppedDown=false " +
this.SelectedIndex + " " + this.Text);
e.Handled = true;
}
}
}
#endregion
#region OnSelectedIndexChanged
protected override void OnSelectedIndexChanged(EventArgs e)
{
Console.WriteLine("OnSelectedIndexChanged " +
this.SelectedIndex + " " + this.Text);
base.OnSelectedIndexChanged(e);
}
#endregion
#region OnDropDownClosed
protected override void OnDropDownClosed(EventArgs e)
{
Console.WriteLine("OnDropDownClosed " +
this.SelectedIndex + " " + this.Text);
base.OnDropDownClosed(e);
}
#endregion
}
控制台输出是这样的(选择项:0,按回车的时候尝试改成2,关闭DropDown后索引还是0):
OnSelectedIndexChanged 0 项目0
OnSelectedIndexChanged 2 item2
ENTER - 在 DroppedDown=false 2 item2 之前
OnDropDownClosed 0 item2
ENTER - 在 DroppedDown=false 0 item2 之后