I have a custom class CheckboxHeaderCell inherit from DataGridViewColumnHeaderCell to add checkbox into any datagridview. The checkbox added successfully, but on checkbox checked event only custom class event trigger but the event in the form (method HeaderCell_CheckedChanged) where I added this checkbox never triggers.
Class: CheckboxHeaderCell
using System;
using System.Drawing;
using System.Windows.Forms;
namespace test.CustomControls
{
public class CheckboxHeaderCell : DataGridViewColumnHeaderCell
{
public event EventHandler CheckedChanged;
public CheckBox checkBox;
public bool IsChecked = false;
public CheckboxHeaderCell()
{
checkBox = new CheckBox();
checkBox.BackColor = SystemColors.Control;
checkBox.Margin = new Padding(0);
checkBox.Padding = new Padding(0);
checkBox.Size = new Size(14, 14);
checkBox.UseVisualStyleBackColor = true;
checkBox.CheckedChanged += CheckBox_CheckedChanged;
CheckedChanged = new EventHandler(doNothing);
}
public void CheckBox_CheckedChanged(object sender, EventArgs e)
{
IsChecked = checkBox.Checked;
CheckedChanged?.Invoke(this, EventArgs.Empty);
if (DataGridView != null)
{
DataGridView.InvalidateCell(this);
}
}
public void doNothing(object sender, EventArgs e)
{
}
//other methods, paint etc
}
}
I used this class to add custom checkbox into my dgv using below method:
private void AddCheckBoxDGV(DataGridView dgv, string columnName)
{
if (dgv.Columns.Contains(columnName))
{
CustomControls.CheckboxHeaderCell checkboxHeaderCell = new CustomControls.CheckboxHeaderCell();
checkboxHeaderCell.CheckedChanged += HeaderCell_CheckedChanged;
dgv.Columns[columnName].HeaderCell = checkboxHeaderCell;
}
}
private void HeaderCell_CheckedChanged(object sender, EventArgs e)
{
//do smthing
}

Your custom
HeaderCelldoes nothing but creates aCheckBoxthat you will never see or access as UI element. Neither on theHeaderCellnor anywhere else on the grid. So, I don't understand how:You must add a Control to some
Parent.Controlscollection and thatParentmust be added directly (itself) or indirectly (its parent) to a top-level control. AFormfor example. TheHeaderCellis not a Control to be used as such.To proof the concept, add the
CheckBoxtoyourGrid.Controls, you'll see it at the very top left, tick it and you'll get theCheckedChangedevent raised.I understand that you need a custom
DataGridViewCheckBoxColumnwith a master CheckBox on theHeaderCellto check/uncheck all. Here's an example.▶ HeaderCell
In the first section, derive a new class from
DataGridViewColumnHeaderCelland,CheckStateof the master CheckBox.Checkedif all the cells are checked,Uncheckedif non, andIndeterminateif not all are checked.OnMouseClickmethod to toggle the state and set the property which,Valueproperty of the owning column's cells totrueorfalse.CheckStatechanges to different value.The second section is to update the state of the master CheckBox when some relevant events of the
DataGridViewoccur. For example, when the user tick/untick a cell of the owning column, when adding or removing rows ...The last section here, drawing the master CheckBox. Override the mouse events to update the mouse state which is used in the
Paintmethod to determine whichCheckBoxStateto draw. I'll use theCheckBoxRendererto draw theCheckBoxin this example. You can try theControlPaint.DrawCheckBoxinstead or draw it the way you want.For the
HeaderCellcustom event, the following custom event arguments class is used to pass the new state.For some thoughts, See:
▶ Column & Cell
Derive a new class from
DataGridViewCheckBoxCell. Unless you want to override thePaintmethod to draw the CheckBox yourself. You don't need to do anything here. It's mainly used to set theCellTemplateof the column class.... and derive another from
DataGridViewCheckBoxColumn.▶ Implementation
Compile and add the custom column by the designer. You'll find in the grid's columns designer a new item is listed and named
CheckAllCheckBoxColumn. You need to subscribe to theCheckedChangedevent by code though. Assuming the column name ischeckAllColumn:Or, do it all by code: