.Net DataGridViewのセルのチェックボックスの制御
DataGridView便利でよくつかいますよね?
日本人は表が好きなので、なんでもグリッドにすることが多いかと思います。
そこで、グリッドのセルにチェックボックスも、ウィザードで簡単に追加できるかと思います。
データの設定も、grid.DataSource = で一発で設定できるし便利便利!!
と思っていたのですが、チェックボックスの制御をしようと思うと途端に難しくなります。
普通は、各オブジェクトからイベントが発生するので、そのイベントに応じて処理を書けばよいのですが、DataGridViewのセルのチェックボックスからはイベントが発生しません。
普通は、CheckedChanged、CheckStateChanged、Clickなどのイベントを拾えるのに、、、、、
なので、定石としては、親のDataGridViewのCellMouseClickを拾うのがよいそうです。
ただし、全てのセルに対して、マウスクリックイベントが発生するため、DataGridViewのCellMouseClickを拾ったあとは
eから、RowIndexとColumnIndexを取得し、どのセルがクリックされたかを特定してイベントの処理を行います。
注意点としましては、DataGridViewのCellMouseClickを実行したあと、拾えない内部のチェックボックスのクリックイベントが発生して、データの書き換えを行うようなので、ダイアログボックスを表示したりすると表示がちぐはぐになります。
さらに、キャンセルをしたくても、強制的にチェックボックスのクリックイベントが発生するため、キャンセルできません。
対応するためには、DataGridViewでチェックボックスを定義する際には、ReadOnly = Trueに設定しておきましょう。
それによって、チェックボックスのオンオフのイベントは発生しません。
勝手に変わらないため、CellMouseClickイベントで自力でON/OFFの制御をしましょう。
というわけでサンプルです。
DataGridViewを作成し、列として、3つチェックボックスを追加しています。
ReadOnlyはTrueにしています。
制御用のコードはこちら
If で判定して成立した場合には自力でValueを反転しています。
成立しない場合には、メッセージボックスを出力しています。
試しに、ReadOnlyをFalseにするとおかしな動きをするのがわかると思います。
Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick Dim columnIndex = e.ColumnIndex Dim rowIndex = e.RowIndex Dim dgv As DataGridView = sender Dim row = dgv.Rows(e.RowIndex) If columnIndex = 0 OrElse row.Cells(columnIndex - 1).Value Then row.Cells(columnIndex).Value = Not row.Cells(columnIndex).Value Else MessageBox.Show("左のチェックボックスがONでないと変更できません。") End If End Sub