4

ユーザーがタブで次のコントロールに移動すると、オートコンプリート中に見つかった値が Winforms コンボ ボックスで失われるという問題があります。

以下はコード サンプルです (フォームをポップアップ表示する 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. テストを実行すると、コンボ ボックスがフォーカスされた状態でフォームがポップアップします...
  2. 「bbb3」と入力して、オートコンプリートで対応するアイテムを選択します。テキスト ボックスが更新され、選択した項目として「bbb3」が表示されます。
  3. ここでTABを押します

テキスト ボックスにフォーカスがあり、コンボ選択が「bbb1」に変更されていることがわかります。また、テキスト ボックスには、leave イベントが発生したときは選択された値がまだ 'bbb3' であったが、lost focus イベントが発生したときは 'bbb1' であることが示されていることにも注意してください。

手順 3 のフォーカスを失うためにコンボ ボックスから離れた場所をクリックすると、これと同じ動作が見られます。

ステップ 3 で他のことを行うと、この問題は発生しません。つまり、次の場合:

  • 「入力」を押してください
  • 「上」から「下」を押して「bbb3」に戻ります
  • アイテムをクリック

何か案は?

4

1 に答える 1

1

値は WM_KILLFOCUS メッセージで失われます。ComboBox のサブクラスで WndProc をオーバーライドすると、この問題が解決されました (クリックしてフォーカスを失うことを除いて... しかし、これは Web サイトのダイアログのように閉じると説明できると思います)。残念ながら、手元にあるのは 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
于 2017-04-06T11:52:46.373 に答える