※ This page contains advertisements / PR.

How to Add a CheckBox Column to a DataGridView in C# (WinForms) and Get Checked Values

📋 Table of Contents (click to expand)

When you display a list in a DataGridView, you often want to place a checkbox column on the left edge so users can select specific rows for batch operations (such as bulk delete or bulk print).

In practice, though, developers frequently run into a subtle problem: “When I click a button right after toggling a checkbox, the changed value isn’t picked up correctly on the code side.” This is caused by the timing of when the cell value is committed.

This article walks through the basic steps to add a checkbox column to a DataGridView, and shows the implementation pattern you need to handle the checked state reliably in real-world applications.

Adding a CheckBox Column to a DataGridView

To display checkboxes in a DataGridView, you use the DataGridViewCheckBoxColumn class.

If you bind an object such as a BindingList<T> as the data source, and the bound class exposes a bool property, the DataGridView will automatically generate that property as a checkbox column on screen.

By adding the column explicitly in code, or by controlling the auto-generated column, you can easily create a column that represents an ON/OFF state for each row.

Full Example Code

The following sample uses a BindingList of a custom class as the data source. It detects checkbox toggles immediately and commits the change back to the data source right away.

Form1.cs
using System.ComponentModel;
namespace DataGridView_CheckboxColumn
{
public partial class Form1 : Form
{
// Declare the BindingList (kept as a class member field)
private BindingList<ProductModel> _products = new();
public Form1()
{
InitializeComponent();
InitializeDataGridView();
}
private void InitializeDataGridView()
{
// Register sample data
_products.Add(new ProductModel(false, "P001", "Laptop"));
_products.Add(new ProductModel(false, "P002", "USB Flash Drive"));
dataGridView1.DataSource = _products;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
// Important: this event commits the value to the data source
// the moment the checkbox is toggled.
dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_CurrentCellDirtyStateChanged;
}
// 1. Fires the instant a cell enters the "editing (dirty)" state
private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
// If the currently active cell is a checkbox cell
if (dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
{
// Force the edit to be committed, even while focus is still on the cell
dataGridView1.EndEdit();
}
}
// Click event for the "Show selected items" button
private void btnShowSelected_Click(object sender, EventArgs e)
{
var selectedNames = new List<string>();
// Iterate over the data source and pick items that are checked $IsSelected == true$
foreach (var product in _products)
{
if (product.IsSelected)
{
selectedNames.Add(product.Name);
}
}
if $selectedNames.Count > 0$
{
MessageBox.Show($"Selected products: {string.Join(", ", selectedNames)}");
}
else
{
MessageBox.Show("Nothing is selected.");
}
}
}
public class ProductModel
{
// A bool property is automatically rendered as a checkbox column
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;
}
}
}

💬 Comments