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.