Normally the DataGridView control does not support adding a checkbox in the header cell.
But this doesn’t mean that it is impossible. You can create your own class that inherits from the DataGridViewColumnHeaderCell and use it.
Here’s one class I had created for myself when I needed it. Besides putting the CheckBox in the header cell, it also has a couple of properties and methods to make it behave the way we are used to seeing in normal windows applications. You can modify it as per your needs.
Imports System Imports System.Drawing Imports System.Windows.Forms Imports System.Windows.Forms.VisualStyles Imports System.ComponentModel Public Class DataGridViewCheckBoxHeaderCell Inherits DataGridViewColumnHeaderCell Private CheckBoxBounds As Rectangle Private CellLocation As New Point() Private CheckBoxState As CheckBoxState Public Delegate Sub DataGridViewCheckBoxHeaderCellEventHandler(ByVal sender As Object, ByVal e As DataGridViewCheckBoxHeaderCellEventArgs) Public Event CheckBoxClicked As DataGridViewCheckBoxHeaderCellEventHandler #Region "Properties" Private _CheckBoxAlignment As HorizontalAlignment = HorizontalAlignment.Center Public Property CheckBoxAlignment() As HorizontalAlignment Get Return _CheckBoxAlignment End Get Set(ByVal value As HorizontalAlignment) If Not [Enum].IsDefined(GetType(HorizontalAlignment), value) Then Throw New InvalidEnumArgumentException("value", CInt(value), GetType(HorizontalAlignment)) End If If _CheckBoxAlignment <> value Then _CheckBoxAlignment = value If Me.DataGridView IsNot Nothing Then Me.DataGridView.InvalidateCell(Me) End If End Set End Property Private _Checked As Boolean Public Property Checked() As Boolean Get Return _Checked End Get Set(ByVal value As Boolean) 'If _Checked <> value Then _Checked = value CheckState = IIf(_Checked, CheckState.Checked, CheckState.Unchecked) If Me.DataGridView IsNot Nothing Then Me.DataGridView.InvalidateCell(Me) 'End If End Set End Property Public Property CheckState() As CheckState Get Select Case CheckBoxState Case CheckBoxState.CheckedDisabled, CheckBoxState.CheckedHot, CheckBoxState.CheckedNormal, CheckBoxState.CheckedPressed Return CheckState.Checked Case CheckBoxState.UncheckedDisabled, CheckBoxState.UncheckedHot, CheckBoxState.UncheckedNormal, CheckBoxState.UncheckedPressed Return CheckState.Unchecked Case CheckBoxState.MixedDisabled, CheckBoxState.MixedHot, CheckBoxState.MixedNormal, CheckBoxState.MixedPressed Return CheckState.Indeterminate End Select End Get Set(ByVal value As CheckState) If CheckState <> value Then If MyBase.DataGridView IsNot Nothing AndAlso MyBase.DataGridView.Enabled Then 'enabled state Select Case value Case CheckState.Checked CheckBoxState = CheckBoxState.CheckedNormal _Checked = True Case CheckState.Indeterminate CheckBoxState = CheckBoxState.MixedNormal Case CheckState.Unchecked CheckBoxState = CheckBoxState.UncheckedNormal _Checked = False End Select Else 'disabled state Select Case value Case CheckState.Checked CheckBoxState = CheckBoxState.CheckedDisabled _Checked = True Case CheckState.Indeterminate CheckBoxState = CheckBoxState.MixedDisabled Case CheckState.Unchecked CheckBoxState = CheckBoxState.UncheckedDisabled _Checked = False End Select End If If Me.DataGridView IsNot Nothing Then Me.DataGridView.InvalidateCell(Me) End If End Set End Property #End Region #Region "Methods" Protected Overridable Sub OnCheckBoxClicked(ByVal e As DataGridViewCheckBoxHeaderCellEventArgs) RaiseEvent CheckBoxClicked(Me, e) End Sub Public Sub CheckUncheckEntireColumn(ByVal checked As Boolean) Me.DataGridView.SuspendLayout() For Each row As DataGridViewRow In Me.DataGridView.Rows row.Cells(Me.ColumnIndex).Value = checked Next Me.DataGridView.ResumeLayout(True) Me.DataGridView.RefreshEdit() End Sub Public Sub RefreshCheckState() Dim newState As Boolean = Me.DataGridView.Rows(0).Cells(Me.ColumnIndex).EditedFormattedValue For Each row As DataGridViewRow In Me.DataGridView.Rows If row.Cells(Me.ColumnIndex).EditedFormattedValue <> newState Then Me.CheckState = CheckState.Indeterminate Exit Sub End If Next Me.Checked = newState End Sub #End Region #Region "Override" Protected Overloads Overrides Sub Paint(ByVal graphics As Graphics, ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState As DataGridViewElementStates, ByVal value As Object, _ ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As DataGridViewCellStyle, ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, ByVal paintParts As DataGridViewPaintParts) 'checkbox bounds Dim state As CheckBoxState = Me.CheckBoxState Dim checkBoxSize As Size Dim checkBoxLocation As Point cellLocation = cellBounds.Location checkBoxSize = CheckBoxRenderer.GetGlyphSize(graphics, state) Dim p As New Point() p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (checkBoxSize.Height / 2) Select Case Me.CheckBoxAlignment Case HorizontalAlignment.Center p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (checkBoxSize.Width / 2) - 1 Case HorizontalAlignment.Left p.X = cellBounds.Location.X + 2 Case HorizontalAlignment.Right p.X = cellBounds.Right - checkBoxSize.Width - 4 End Select checkBoxLocation = p checkBoxBounds = New Rectangle(checkBoxLocation, checkBoxSize) 'paint background paintParts = paintParts And Not DataGridViewPaintParts.ContentForeground MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts) 'paint foreground Select Case Me.CheckBoxAlignment Case HorizontalAlignment.Center cellBounds.Width = checkBoxLocation.X - cellBounds.X - 2 Case HorizontalAlignment.Left cellBounds.X += checkBoxSize.Width + 2 cellBounds.Width -= checkBoxSize.Width + 2 Case HorizontalAlignment.Right cellBounds.Width -= checkBoxSize.Width + 4 End Select paintParts = DataGridViewPaintParts.ContentForeground MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, "", errorText, cellStyle, advancedBorderStyle, paintParts) 'paint check box CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, state) End Sub Protected Overloads Overrides Sub OnMouseClick(ByVal e As DataGridViewCellMouseEventArgs) If e.Button = MouseButtons.Left Then 'click on check box ? Dim p As New Point(cellLocation.X + e.X, cellLocation.Y + e.Y) If checkBoxBounds.Contains(p) Then 'raise event RaiseCheckBoxClicked() End If End If MyBase.OnMouseClick(e) End Sub Protected Overloads Overrides Sub OnKeyDown(ByVal e As KeyEventArgs, ByVal rowIndex As Integer) If e.KeyCode = Keys.Space Then 'raise event RaiseCheckBoxClicked() End If MyBase.OnKeyDown(e, rowIndex) End Sub Public Overloads Overrides Function Clone() As Object Dim cell As DataGridViewCheckBoxHeaderCell = TryCast(MyBase.Clone(), DataGridViewCheckBoxHeaderCell) If cell IsNot Nothing Then cell.Checked = Me.Checked End If Return cell End Function #End Region #Region "Private" Private Sub RaiseCheckBoxClicked() 'raise event Dim e As New DataGridViewCheckBoxHeaderCellEventArgs(Not Me.Checked) Me.OnCheckBoxClicked(e) If Not e.Cancel Then Me.Checked = e.Checked Me.DataGridView.InvalidateCell(Me) End If End Sub #End Region End Class #Region "EventArgs Class" Public Class DataGridViewCheckBoxHeaderCellEventArgs Inherits CancelEventArgs Private _Checked As Boolean Public ReadOnly Property Checked() As Boolean Get Return _Checked End Get End Property Public Sub New(ByVal checkedValue As Boolean) MyBase.New() _Checked = checkedValue End Sub Public Sub New(ByVal checkedValue As Boolean, ByVal cancel As Boolean) MyBase.New(cancel) _Checked = checkedValue End Sub End Class #End Region
Sample Usage
Add the above class to your project.
Add a DataGridView control (DataGridView1) to your form and the following code:
Public Class Form1 '' declare our header cell with checkbox Dim WithEvents CheckBoxHeaderCell As DataGridViewCheckBoxHeaderCell Private Sub Form3_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load '' some dummy data source Dim di As New IO.DirectoryInfo("C:\") Dim ds = From fi In di.GetFiles _ Select New With {.FileName = fi.Name, .CreationTime = fi.CreationTime, _ .LastAccessTime = fi.LastAccessTime, .LastModified = fi.LastWriteTime} DataGridView1.DataSource = ds.ToList DataGridView1.Columns.Insert(0, New DataGridViewCheckBoxColumn) '' our checkbox in header cell CheckBoxHeaderCell = New DataGridViewCheckBoxHeaderCell DataGridView1.Columns(0).HeaderCell = CheckBoxHeaderCell End Sub Private Sub CheckBoxHeaderCell_CheckBoxClicked(sender As Object, e As DataGridViewCheckBoxHeaderCellEventArgs) Handles CheckBoxHeaderCell.CheckBoxClicked CheckBoxHeaderCell.CheckUncheckEntireColumn(e.Checked) End Sub Private Sub DataGridView1_CellContentClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick If e.ColumnIndex = CheckBoxHeaderCell.ColumnIndex Then CheckBoxHeaderCell.RefreshCheckState() End Sub End Class
Run the program.
Notice that your header cell has a checkbox. Click the checkbox in header cell and observe that the entire column gets checked/unchecked. Click the checkbox in any of the rows and observe that the checkbox in header cell sets its state accordingly.
Enjoy!
—
August 2, 2012 at 1:50 pm
This is absolutely fantastic, exactly what I was looking for. Example example, thank you very much.
August 2, 2012 at 1:51 pm
Sorry, excellent example, not “example example”
August 3, 2012 at 8:38 am
I’m glad this helped you 🙂
August 15, 2012 at 3:36 pm
Thank you a lot for this code! A lot of time has elapsed since publication date. Could you please give me a tip? How to assign a text to the header of the text box column?
August 15, 2012 at 4:09 pm
There should be nothing special about it, unless I’m not getting what you are trying to ask. You can do just as you would do for any other type of Column:
e.g.
DataGridView1.Columns(0).HeaderText = “whatever”
August 16, 2012 at 7:03 am
Thank you a lot for the answer. On this page http://www.codeproject.com/Articles/20165/CheckBox-Header-Column-For-DataGridView code works as you mentioned. I am will try to find the reason.
November 14, 2013 at 2:07 pm
Amigo estube probando el codigo y esta fantastico, pero el mismo tienen una pequeña falla, cuando activas o desactivas una sola columna, este evento no actualiza el el estado de la columna de tipo Check, pero esto es un error de la libreria de Visual Studio. afortunadamente buscando por internet pude encontrar la solucion, la siguiente parte de codigo la encontre del siguiente enlace:
http://geeks.ms/blogs/fernandezja/archive/2008/07/15/datagridviewcheckboxcolumn-detectar-el-cambio-check-en-el-evento-cellvaluechanged.aspx
Para no entrar en mas detalles si quieren saber el porque del error pueden leer el enlaces que les coloque
en lugar de este evento:
Colocar este evento:
Y ademas colocar el siguiente evento:
Gracias por el aporte.
November 14, 2013 at 2:13 pm
My friend, i was testing the code and this fantastic, but it has a small flaw, when you activate or deactivate a single column, this event does not update the status column of type check, but this is a library error Visual Studio. fortunately searching the internet I could find the solution, the next part of the code I found the following link (in Spanish):
http://geeks.ms/blogs/fernandezja/archive/2008/07/15/datagridviewcheckboxcolumn-detectar-el-cambio-check-en-el-evento-cellvaluechanged.aspx
instead of this event:
Put this another event:
And additionally place this new event:
November 18, 2014 at 3:35 pm
thank’s
September 17, 2015 at 2:40 pm
How to add a checkbox in all column instead of rows. Can you pls educate me.Thx
September 17, 2015 at 10:02 pm
We are adding checkbox in the column (as also shown in the sample and screenshot), and not the rows. Did you mean something else?
I showed how to add checkbox in 1 column. The same procedure may be applied for multiple columns too.
November 12, 2015 at 6:45 pm
I think the key here is to make the overall Grid NOT “read only” and make your individual columns “read only” or not as needed. Obviously it’s important for the check box column NOT to be read only. Thanks for the code and all the subsequent comments!
August 19, 2017 at 9:08 am
Superb !!! Code is working.
June 14, 2019 at 7:22 pm
Hello!
Would not you have the same code for CSharp #?
I tried to do the conversion but I could not!
March 26, 2020 at 1:20 pm
I know this article is very old but I just want to tel you thank a lot because it’s still helpfull.
July 19, 2020 at 11:26 am
Excellent!. You’re simply the best. Thank you!
March 15, 2021 at 8:52 pm
This does everything I want except I am struggling to get the text into the check box so that the user knows what that column is for – I have tried the following
CheckBoxHeaderCell = New DataGridViewCheckBoxHeaderCell
DataGridView1.Columns(7).HeaderCell = CheckBoxHeaderCell
DataGridView1.Columns(7).HeaderText = “Exclude”
but I only see the HeaderText when I hover over the Header cell – what am I doing wrong?