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