DataGridView:チェックボックス列の表示とチェック状態を取得する方法(サンプルあり)

📋 目次(クリックで展開)

DataGridView で一覧を表示する際に、特定の行を選択して一括処理(一括削除や一括印刷など)を行うために、左端にチェックボックス列を配置したいケースは多いです。

しかし、実際に配置してみると「チェックを付け外しした直後にボタンを押しても、変更した値がプログラム側でうまく取得できない」といった、イベント発生タイミングの挙動に悩まされることがあります。

今回は、DataGridView にチェックボックス列を追加する基本手順と、実務でトラブルなくチェック状態を扱うための実装方法について解説します。

チェックボックス列の基本概念と追加方法

DataGridView でチェックボックスを表示するには、DataGridViewCheckBoxColumn クラスを使用します。

データソースに BindingList<T> などのオブジェクトをバインドしている場合、バインド元のクラスのプロパティが bool であれば、DataGridView は自動的にチェックボックス列として画面に生成してくれます。

コード側で明示的に列を追加、または自動生成された列を適切に制御することで、行ごとの ON/OFF を表現する列を簡単に作成することができます。

実装コード

以下は、独自クラスの BindingList をデータソースとし、チェックボックスの切り替えを即座に検知してデータソース側に反映するサンプルコードです。

Form1.cs
using System.ComponentModel;
namespace DataGridView_CheckboxColumn
{
public partial class Form1 : Form
{
// BindingListの宣言(クラスのメンバ変数として保持します)
private BindingList<ProductModel> _products = new();
public Form1()
{
InitializeComponent();
InitializeDataGridView();
}
private void InitializeDataGridView()
{
// サンプルデータの登録
_products.Add(new ProductModel(false, "P001", "ノートパソコン"));
_products.Add(new ProductModel(false, "P002", "USBメモリ"));
dataGridView1.DataSource = _products;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
// 重要:チェックを入れた「瞬間」にデータソースに値を確定させるためのイベント
dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_CurrentCellDirtyStateChanged;
}
// 1. セルの状態が「編集中(Dirty)」になった瞬間に呼び出されるイベント
private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
// 現在アクティブなセルがチェックボックス列の場合
if (dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
{
// まだフォーカスがセルに残っていても、強制的に編集を確定(コミット)させる
dataGridView1.EndEdit();
}
}
// 「選択された項目を表示」ボタンのクリックイベント
private void btnShowSelected_Click(object sender, EventArgs e)
{
var selectedNames = new List<string>();
// データソース側を走査して、チェック(IsSelected == true)がついているものを抽出
foreach (var product in _products)
{
if (product.IsSelected)
{
selectedNames.Add(product.Name);
}
}
if (selectedNames.Count > 0)
{
MessageBox.Show($"選択された商品: {string.Join(", ", selectedNames)}");
}
else
{
MessageBox.Show("何も選択されていません。");
}
}
}
public class ProductModel
{
// bool型のプロパティは自動的にチェックボックス列になります
public bool IsSelected { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public ProductModel(bool isSelected, string code, string name)
{
IsSelected = isSelected;
Code = code;
Name = name;
}
}
}

実行結果

「IsSelected」列にチェックボックスが表示されていることが分かります。また、チェックのステータスが、即座にデータソースに確定・反映されます。

サンプルアプリケーション

DataGridView_CheckboxColumn.zip
※ サンプルアプリケーションは、.NET 9 をターゲットに作成しています。

注意点:CurrentCellDirtyStateChanged が必要な理由

DataGridView のチェックボックス列を扱う際、上記コードにある CurrentCellDirtyStateChanged イベントの記述が省略されている実装に出くわすことがあります。しかし、このイベントを実装していないと、実務のアプリケーションでは致命的なバグの原因になります。

DataGridView の標準の挙動では、ユーザーがチェックボックスをクリックしてON/OFFを切り替えても、**「そのセルから別のセルへフォーカスを移動する(あるいはEnterキーを押す)」までは、内部データが確定(コミット)されません。**これはおそらく、編集状態と非編集状態を明確に分けるという、DataGridView の設計思想のためだと思われます。

そのため、このイベントを入れ忘れると、「ユーザーがチェックボックスをクリックした直後に、どこにも移動せず画面下の『実行ボタン』を押した場合、クリックしたはずのチェックがデータソース側に反映されず、未選択として処理されてしまう」 という不具合が発生します。

チェックを入れた「その瞬間」にデータを同期させるために、CurrentCellDirtyStateChanged 内で dataGridView1.EndEdit() を呼び出すテクニックは、実務でのチェックボックス列の実装において必須のセットと言えます。

まとめ

今回は、DataGridView にチェックボックス列を追加する方法と、実務で安全にその状態を取得するための実装パターンについて解説しました。

チェックボックス列はユーザーにとっても直感的で非常に便利な UI ですが、データの確定タイミングという特有の仕様が存在します。

CurrentCellDirtyStateChanged イベントを使ってデータソースとの同期タイミングを適切に交通整理してあげれば、クリックの取りこぼしがない堅牢な一覧画面を構築することができます。

一括処理や複数選択機能を備えた業務アプリ画面を開発する際の、参考になりましたら幸いです。


💬 コメント