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 ドロップダウンとオートコンプリート ウィンドウの両方が表示されます) 。

ComboBox を検証し、テキストが入力されたときに最初に一致する項目を選択するロジックを実装しました。

DropDown が表示され、ユーザーが何かを入力して Enter キーを押すと、最初に一致した項目が選択されます。次に、DropDown を閉じたいと思います。ComboBox.DroppedDown プロパティを false に設定して行います。問題は、DropDown がこのように閉じられると、選択された項目が以前に選択された項目にリセットされることです。OnSelectedIndexChanged、OnSelectionChangeCommitted、および OnSelectedValueChanged は呼び出されません。

OnSelectedIndexChanged で選択したインデックスを記憶し、OnDropDownClosed で再度設定することで対処します (DropDown が手動で閉じられた場合)。

質問: ComboBox の DroppedDown プロパティが false に設定されていると、選択した項目、インデックス、テキスト、および値がリセットされるのはなぜですか? この副作用のない ComboBox を手動で閉じる別の方法はありますか?

編集:問題を説明するコード:

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、Enter キーを押しながら 2 に変更してみてください。ドロップダウン インデックスを閉じた後も 0 のままです)。

OnSelectedIndexChanged 0 item0

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 に答える