mamori017.log

歴史的クソブログ

DataGridView上のデータを絞り込み表示する

DataGridViewに表示されているデータに対して、絞り込み条件を指定し表示させたい場合は BindingSourceクラスのFilterプロパティが使用できる。

BindingSource.Filter プロパティ (System.Windows.Forms)

手順
  1. DataGridViewにバインドしたDataSourceをDataTableとして取得する。
  2. DataTableをBindingSource.DataSourceプロパティにセットする。
  3. BindingSource.Filterプロパティに絞り込み条件を設定する。
  4. Filterに設定した条件で絞り込みされた結果がDataGridViewに表示される。

フォーム上のテキストボックスに入力された値がDataGridViewに対しての絞り込み条件としたとき、 TextChangedイベントが発生するたびにフィルター処理を呼ぶようにハンドラを追加する。 見かけ上分かりやすかったのでTextChangedをイベントに指定しているが、このイベント自体は別に何でも良い。

''' ロード時の初期設定
Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    ' テキストボックスに変更があった場合のイベントハンドラを追加する
    AddHandler txt_Condition.TextChanged, AddressOf DataGridViewFilter
End Sub

テキストボックスがTextChangedイベントを発生するたびに呼び出される関数上で、 絞り込み条件の記述を整形し、BindingSourceにデータと絞り込み条件を設定する。

Private Sub DataGridViewFilter()
    Dim objBind As BindingSource
    Dim objData As DataTable
    Dim strFilter As String

    ' DataGridViewにバインドしたデータをDataTableとして取得する
    objData = CType(DataGridView1.DataSource, DataTable)

    ' データが存在する場合
    If IsNothing(objData) = False Then
        objBind = New BindingSource
        ' バインドするデータソースにDataTableをセット
        objBind.DataSource = objData
        ' DataGridViewの表示内容を絞り込むための条件式を設定する
        strFilter = "Color like '%" & txt_Condition.Text & "%'"
        ' データソースにフィルターをセット
        objBind.Filter = strFilter
    End If
End Sub

DataGridViewが以下の状態で表示されている場合、

Seq Month Day Color
1 8 1 Orange
2 4 17 Blue
3 9 19 Light Pink
4 3 4 Yellow
5 9 21 Pink
6 7 13 White
7 1 1 Red
8 2 10 Green
9 6 13 Purple

テキストボックスにPinkと入力があった場合、DataGridViewに対する絞り込み条件はColor like '%Pink%'となる。 あとはこの条件式をBindingSourceにセットすることでDataGridViewの表示状態は以下のように変更される。

Seq Month Day Color
3 9 19 Light Pink
5 9 21 Pink

記述した内容だと入力の都度TextChangedイベントが発生してしまう。 絞り込みの条件句を部分一致にしているので、Pと入力した時点でTextChangedイベントが発生し、 Light PinkPinkPurpleの3件が表示される。 このあたりの振る舞いは別のイベントで制御するほうがスマートかもしれない。*1

この記事は今度書き直す。

*1:とはいえEnterキーとか検索ボタンをトリガーにしたくないという要望があってこのまま実装した。