落とし穴、と言いますか、やっぱり ComboBox コントロールの落とし穴っぽい動きの話です。
■問題
単純にフォームに ComboBox コントロールを貼り付けて、項目を選択した直後のイベントを拾いたい。
さてどうするのか?
という要件があって、なんか手元のコードでは、SelectedIndexChanged イベントを拾っていた訳です。
SelectedIndexChanged イベントでも悪くはないのですが、ComboBox で項目を選択している途中のイベントも拾ってしまうので、【最後のイベントだけを拾う】ってのがなかなかでき難い、というか、これでバグっているので。
■イベントは4種類ある
あらためて ComboBox のイベントを見ると、それらしいものが4つほどあります。
・SelectedIndexChanged イベント:選択項目が変更されるたびに発生する
・SelectionChangeCommitted イベント:項目がコミットするタイミングで発生する
・DropDownClosed イベント:ドロップダウンのリストが、閉じられるタイミングで発生する
・TextChanged イベント:ComboBox のテキストが変更されるタイミングで発生する
■試行錯誤してみる
↓なコードを書いて、発生するイベントを見てみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Private Sub ComboBox1_SelectedIndexChanged( ByVal sender As System. Object , ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged Debug.Print( "ComboBox1_SelectedIndexChanged" ) End Sub Private Sub ComboBox1_SelectionChangeCommitted( ByVal sender As System. Object , ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted Debug.Print( "ComboBox1_SelectionChangeCommitted" ) End Sub Private Sub ComboBox1_DropDownClosed( ByVal sender As System. Object , ByVal e As System.EventArgs) Handles ComboBox1.DropDownClosed Debug.Print( "ComboBox1_DropDownClosed" ) End Sub Private Sub ComboBox1_TextChanged( ByVal sender As System. Object , ByVal e As System.EventArgs) Handles ComboBox1.TextChanged Debug.Print( "ComboBox1_TextChanged" ) End Sub |
動かし方は、
・マウスで選択する。
・マウスでスクロールバーを動かす。
・キーボードでリストを選択する。
・リストを閉じたままで、キーボードで動かす。
のパターンがあります。
一見すると、SelectedIndexChanged イベントで良いような気もするのですが、リストを選択している途中もバシバシとイベントが発生するので駄目です。
マウスで動かしているときは発生しないのですが、キーボードの矢印キーで動かすと連続して発生します。
じゃあ、SelectionChangeCommitted でもいいのかな、と思っていると。
リストを閉じる時に、右にある▼をクリックすると、SelectionChangeCommitted イベントが発生しないという落とし穴…なんじゃそりゃ?状態なので、ちょっと使えません。
そうなると、DropDownClosed イベントでリストが閉じられるタイミングを拾えばよいのでは?と思うのですが、
きちんと▼を押して、リストから選択するときは良いのですが、リストを出さずに上下のカーソルキーで直接動かすときには、実は DropDownClosed イベントが発生しないのです。えぇ SelectionChangeCommitted イベントは発生するんですけどね。
そんな訳で、素直に TextChanged イベントを使うのが無難ですね…という結論でした。
ただ、TextChanged イベントの場合は、編集可能な ComboBox のときにはイベントがややこしいんですよね…悩ましい、という話
分かりやすい説明でした。ありがとう。
どういたしまして。
TextChanged イベントに落ち着くべきところに落ち着いたって感じなんですけどね。理想を言えば、マウスでもカーソルキーでも似た操作は同じイベントが発生してほしいのですが…どうも、ComboBox の実装って MFC の頃から変なんですよね。
有名なRevaバレエのフラット、貰えます含むセミ手頃な価格の贅沢を提供していますでしたアパレル、女の子のアパレル、靴と機器。何ですより多く、あなた払う必要がありますカップル何百ものにドル新しいのペアサングラス中程度の選択肢RayBanのようなさらにREVO。
VisualStudio2015のC#で初っ端にComboBox にTextChangedのメソッドを設定してもComboBox の選択でイベントが飛んでこず、SelectedIndexChangedのメソッドを設定したらTextChangedイベントも飛んで来るようになり、SelectedIndexChangedを削除してもTextChangedイベントメソッド有効のまま、という不思議な現象が起こりました。
リビルドしないのがダメなのかなとやってみても変わらず。
一応、報告まで。