さて、 今回はカテゴリ選択の部分で使っているComboBoxコントロール、別名ドロップダウンリストについて解説します。
これも非常に良く使われるコントロールなのですが、ボタン(Button)やテキストボックス(TextBox)よりも機能が多い分、使いこなす為にはしっかりと仕組みを理解しておく必要があります。
また、この記事では前回説明していなかった RefreshDropDownList メソッドについても解説したいと思います。
ComboBoxの構成とイベント
それでは、ComboBoxの構成とイベントについて見ていきましょう。
ComboBoxはテキスト入力を行う「テキストボックス部」と、リストから項目を選択する「ドロップダウンリスト部」で構成されています。
ちなみに、テキストボックス部は単にテキスト部、ドロップダウンリストは単にリスト部と表現することもあります。
そして、ComboBoxへの操作に応じたイベントが発生するようになっています。
ComboBox で扱えるイベントはいくつもあるのですが、下図は代表的なもの4つをピックアップしています。

単に値を選択したり、文字列を入力するだけであれば、特にイベントハンドラは使いません。
一般的に
- ユーザーの処理に応じてドロップダウンリストの内容を変えたい(DropDownイベント)
- 項目を選択した瞬間に別の処理を行いたい(SelectedIndexChangedイベント)
- テキストボックス部に入力された値によって処理を行いたい(TextChangedイベント)
など、ユーザーの操作に応じて処理を変えたい時、イベントハンドラを使います。
カテゴリ選択に関するイベント
パスワード管理ツールのカテゴリ選択で使っているイベントは、DropDown と SelectedIndexChanged の2つです。
そして、IDとパスワードの編集が完了した際、ドロップダウンの内容を作り直すため、RefreshDropDownList() というメソッドを記述しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/// <summary> /// カテゴリドロップダウンリスト表示時の処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UxCategory_DropDown(object sender, EventArgs e) { //カテゴリドロップダウンリストの中身が0なら、作り直す if (uxCategory.Items.Count == 0) { RefreshDropDownList(); } } /// <summary> /// カテゴリドロップダウンの再作成 /// </summary> private void RefreshDropDownList() { uxCategory.Items.Clear(); uxCategory.Items.Add(""); for (int i = 0; i < uxIdPasswordGrid.Rows.Count; i++) { var category = uxIdPasswordGrid["カテゴリ", i].Value; if (! uxCategory.Items.Contains(category)) { uxCategory.Items.Add(category); } } } /// <summary> /// カテゴリドロップダウンリスト選択時の処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UxCategory_SelectedIndexChanged(object sender, EventArgs e) { var dt = (DataTable)uxIdPasswordGrid.DataSource; if (uxCategory.Text == "") { dt.DefaultView.RowFilter = ""; } else { dt.DefaultView.RowFilter = "カテゴリ = '" + uxCategory.Text + "'"; } uxIdPasswordGrid.DataSource = dt; } |
DropDownイベント
まず、DropDownイベントでは、ドロップダウンリストを開いた時、ドロップダウンリストの項目が0だった場合のみ、ドロップダウンリストを再作成するようにしています。
ドロップダウンリストに登録されている項目数は、uxCategory.Items.Count というプロパティで参照可能です。
1 2 3 4 |
if (uxCategory.Items.Count == 0) { RefreshDropDownList(); } |
RefreshDropDownListメソッド
では、RefreshDropDownList() メソッドの中身を見てみましょう。
1 2 3 |
uxCategory.Items.Clear(); uxCategory.Items.Add(""); |
ここで、Itemsというプロパティが登場しました。
このプロパティはComboBox.ObjectCollection というクラスで、Addメソッドを使って、あらゆる型の値を登録することが出来ます。
そして、ここに登録した値が、ドロップダウンリストに表示されます。

Addメソッドの前に Clear メソッドを読んでいますが、これは ComboBox.ObjectCollection の中身を空にするためのメソッドです。
これを呼ばないと、前回Addした値が残った状態で追加されるので、ドロップダウンリストを開く度、Itemsに登録されている値が増えていく事に成ります。
次に Add(“”) で空文字を登録していますが、これはドロップダウンリストで未入力が選択できるようにするためです。
未入力を選択することで、絞り込みフィルターの条件を空にし、絞り込み状態を解除するようにしています。
次に DataGridView の行数だけループして、”カテゴリ”列の値を ComboBox.ObjectCollection に登録しています。
1 2 3 4 5 6 7 8 9 |
for (int i = 0; i < uxIdPasswordGrid.Rows.Count; i++) { var category = uxIdPasswordGrid["カテゴリ", i].Value.ToString(); if (! uxCategory.Items.Contains(category)) { uxCategory.Items.Add(category); } } |
この処理の注意点としては、単にループしながらカテゴリ名を登録していくと、同じカテゴリが複数登録されてしまうという点です。
そこで、これから登録しようとするカテゴリの値が、 ComboBox.ObjectCollection に存在するか否かを Contains メソッドを使って確認しています。
Contains メソッドの戻り値が true なら既に登録済みということなので、! 演算子で戻り値を反転しています。
こうすることによって false が返ってきた場合の結果を true にし、if 文の処理が実行される(=Addにより登録される)ようにしています。
ちなみに、この if 文は次の様に書く事も可能です。
1 2 3 4 |
if (uxCategory.Items.Contains(category) == false) { uxCategory.Items.Add(category); } |
どちらが良いというより好みの問題ですが、自分にとってより分かりやすいと思う書き方を選べばよいかと思います。
SelectedIndexChangedイベント
SelectedIndexChangedイベントは、ドロップダウンリストを選択した時のイベントですので、ここにフィルターによる絞り込み処理を記述しています。
やりたい事は
- DataGridViewの DataSource プロパティからDataTableを取得
- カテゴリComboBoxのを DataTableのDefaultView.RowFilter プロパティに代入
の2点です。
カテゴリ ComboBoxのドロップダウンを選択した結果は、 Text プロパティに代入されます。
Textプロパティが空文字 “” であれば、DefaultView.RowFilterプロパティに空文字を代入し、そうでない場合は絞り込み条件を代入しています。
1 2 3 4 5 6 7 8 9 10 11 |
var dt = (DataTable)uxIdPasswordGrid.DataSource; if (uxCategory.Text == "") { dt.DefaultView.RowFilter = ""; } else { dt.DefaultView.RowFilter = "カテゴリ = '" + uxCategory.Text + "'"; } |
DefaultView.RowFilter に代入する絞り込み条件の書き方はデータベースで使われるSQLに似た書き方をします。
詳しくは、こちらの記事の目次「データのフィルタリングとソート」をご参照下さい。
今回は、 「カテゴリ列の値が カテゴリComboBox.Text の値と等しい」という内容の条件を代入しています。
まとめ
如何でしたでしょうか。
今回はComboBoxのイベントについて解説致しました。
単に値を選択したいだけなら、イベントハンドラは特に必要ありませんが、今回のように画面からの入力に応じた処理を行う場合は、該当するイベントハンドラに処理を記述する必要があります。
次回はDataGridViewのキー入力イベントについて解説したいと思います。