I'm trying to render a checkbox in a datagridview column header so that when the checkbox is checked/unchecked all the cells in that column should be
checked/unchecked accordingly. The datagridview is bound to a database table but the column containing the checkbox header cell is unbound.
The problem is, whenever i click the header checkbox, all the cells in that column are checked but the header checkbox itself gets invisible.
If I click the HEADER (though the checkbox is invisible, still I can click the header) again, all the cells in the column below are unchecked and the header
checkbox becomes visible and unchecked. Everything is happening as expected except the visibility of the header checkbox. Why is it so?
Please suggest how to get rid of it. Regards.
My code follows below:
Expand|Select|Wrap|Line Numbers
- ''' <summary>
- ''' The custom class for checkbox header cell.
- ''' </summary>
- Imports System.Drawing
- Public Delegate Sub CheckBoxClickedHandler(ByVal state As Boolean)
- Public Class DataGridViewCheckBoxHeaderCellEventArgs
- Inherits EventArgs
- Private _bChecked As Boolean
- Public Sub New(ByVal bChecked As Boolean)
- _bChecked = bChecked
- End Sub
- Public ReadOnly Property Checked As Boolean
- Get
- Return _bChecked
- End Get
- End Property
- End Class
- Public Class DataGridViewCheckBoxHeaderCell
- Inherits DataGridViewColumnHeaderCell
- Private checkBoxLocation As Point
- Private checkBoxSize As Size
- Private _checked As Boolean = False
- Private _cellLocation As New Point
- Private _cbState As Windows.Forms.VisualStyles.CheckBoxState = VisualStyles.CheckBoxState.UncheckedNormal
- Public Event OnCheckBoxClicked As CheckBoxClickedHandler
- Public Sub New()
- End Sub
- Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
- MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
- Dim p As New Point
- Dim s As Size = CheckBoxRenderer.GetGlyphSize(graphics, Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal)
- p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2)
- p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (s.Height / 2)
- _cellLocation = cellBounds.Location
- checkBoxLocation = p
- checkBoxSize = s
- If _checked Then
- _cbState = Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal
- Else
- _cbState = Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal
- CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState)
- End If
- End Sub
- Protected Overrides Sub OnMouseClick(ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
- Dim p As New Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y)
- If p.X >= checkBoxLocation.X And p.X <= checkBoxLocation.X + checkBoxSize.Width And p.Y >= checkBoxLocation.Y And p.Y <= checkBoxLocation.Y + checkBoxSize.Height Then
- _checked = Not _checked
- RaiseEvent OnCheckBoxClicked(_checked)
- Me.DataGridView.InvalidateCell(Me)
- End If
- MyBase.OnMouseClick(e)
- End Sub
- End Class
- ''' <summary>
- ''' Actual class where the custom class is used.
- ''' dgvContacts is the name of the datagridview.
- ''' colCheck is the name of the column containing the checkbox header cell.
- ''' </summary>
- Public Class ContactList
- 'Other declarations...
- ......................
- ......................
- Private WithEvents _cbHeader As DataGridViewCheckBoxHeaderCell
- Sub New()
- ' This call is required by the designer.
- InitializeComponent()
- ' Add any initialization after the InitializeComponent() call.
- _cbHeader = New DataGridViewCheckBoxHeaderCell
- colCheck.HeaderCell = _cbHeader
- colCheck.HeaderText = ""
- colCheck.Visible = True
- End Sub
- 'Other definitions...
- .....................
- .....................
- Private Sub _cbHeader_OnCheckBoxClicked(ByVal state As Boolean) Handles _cbHeader.OnCheckBoxClicked
- For i As Integer = 0 To dgvContacts.RowCount - 1
- dgvContacts("colCheck", i).Value = state
- Next
- dgvContacts.EndEdit()
- End Sub
- End Class