1

我有一个继承表单 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 之后

4

2 回答 2

1
    protected override void OnDropDownClosed(EventArgs e)
    {
        Console.WriteLine("OnDropDownClosed " +
             this.SelectedIndex + " " + this.Text);


        int idx = this.SelectedIndex;

        base.OnDropDownClosed(e);

        this.SelectedIndex = idx;


    }
于 2013-03-04T04:27:13.967 回答
0

我发现设置 SelectedItem 比设置 SelectedIndex 更可靠。

//这也会改变 SelectedIndex 并触发 SelectedItemChanged 事件。

this.SelectedItem = this.Items[idx];

于 2015-01-13T13:50:26.873 回答