3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(.Net)DataGridViewでソートするとチェックボックス列の値が消える

DataGridView で DB から取得した DataTable をデータソースとしてバインドし、DataGridViewCheckBoxColumn 列を追加しました。

その状態で、何かチェックを付けてソートすると、チェックが全て消えるという現象が発生。

調べてみると、uedakoの日記:DataGridViewとチェックボックスとソートの話で同じ現象で悩んでる人発見。

どうやら、バインド列と非バインド列が混在してる場合、こうなるのがMSの仕様だそうです。

確かに、MSDN:Windows フォーム DataGridView コントロール内の列の並べ替えモードをみると、そう書かれています。

で、ソート時に非バインド列で値を保持するためには、DataGridView.VirtualMode = True にして、仮想モードでやればいいようです。

しかし、これをすると様々な動作を自分で書いて実装しないと行けないらしく非常に面倒です。(仮想モードは大量のデータをグリッドに表示するときにパフォーマンスを落とさないようするときに使う場合が多いみたい)

一応仮想モード時のサンプルがMSDN:方法 : Windows フォーム DataGridView コントロールで仮想モードを実装するにあるんですが、ちらっと見たところやっぱり面倒くさそうです。

それで、DBから取得した後の DataTable に対して Boolean 型の DataColumn を追加して、それを DataGridView にバインドさせる方法をとることにしました。

なお、チェックボックス列は先頭に表示することとします。(DataGridViewColumnの DisplayIndex プロパティで指定)

コードはこんな感じです。

Public Class Form1

'TableAdapter VisualStudioのDataSetデザイナが作ってくれたやつ使用

Private m_adp As New Database1DataSetTableAdapters.table1TableAdapter()

'DBから取得したデータを保存してる DataTalbe

Private m_tbl As DataTable

 

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

'DBからデータ取得

m_tbl = m_adp.GetData()

 

'DataTable にチェックボックス用の Boolean 列用意

Dim clmCheck As New DataColumn("check", Type.GetType("System.Boolean"))

m_tbl.Columns.Add(clmCheck)

 

'グリッドにバインド

Me.DataGridView1.DataSource = m_tbl

 

'チェックボックス用列を最初に表示

Me.DataGridView1.Columns("check").DisplayIndex = 0

Me.DataGridView1.Columns("check").SortMode = DataGridViewColumnSortMode.Automatic

End Sub

End Class

これでちゃんとソートしても値が保持されるようになりました。