다음을 통해 공유


VB.NET: CheckBoxColumn Select All Demo


Overview


Sometimes when using a DataGridView with a DataGridViewCheckBoxColumn, you might need the ability to select or deselect all of the CheckBoxes in that column of your DataGridView by checking or unchecking one CheckBox in the DataGridViewColumn's HeaderCell. There are several ways to achieve this, but placing a control box CheckBox control on the HeaderCell causes scrolling and rendering problems and is ultimately a very unsatisfactory solution.

A more professional method is to extend the DataGridViewColumnHeaderCell, overriding the Paint and OnMouseClick events to draw a custom CheckBox on the DataGridViewColumnHeaderCell, and to respond to clicks on the CheckBox. An additional isChecked Property keeps track of the CheckBox CheckState.

 


The extended DataGridViewColumnHeaderCell

This is the extended DataGridViewColumnHeaderCell:

The isChecked Property holds the current CheckedState of the CheckBox. When this Property changes, all of the CheckBoxes in the DataGridViewCheckBoxColumn, with the exception of the new row, are assigned the new value.

The Paint event draws a standard HeaderCell with the Text offset to the right, which leaves space to draw a CheckBox at the left. The CheckedState of the CheckBox drawn is dependent on the value of the Boolean isChecked Property.

The OnMouseClick event captures clicks in the rectangle occupied by the CheckBox and toggles the Boolean isChecked Property.


 

Public Class  checkHeaderCell
    Inherits DataGridViewColumnHeaderCell
    Dim l As New  Point(6, 5)
    Dim s As New  Size(12, 12)
 
    Private _isChecked As Boolean
 
    Public Property  isChecked() As  Boolean
        Get
            Return _isChecked
        End Get
        Set(ByVal value As Boolean)
            _isChecked = value
            Me.DataGridView.EndEdit()
            For x As Integer  = 0 To  Me.DataGridView.Rows.Count - 1
                If Me.DataGridView.Rows(x).IsNewRow Then  Continue For
                Me.DataGridView.Rows(x).Cells(Me.OwningColumn.Index).Value = value
            Next
        End Set
    End Property
  
    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)
        Dim spaces As New  String(" "c, 6)
        MyBase.Paint(
                graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, 
                spaces & value.ToString.Trim, spaces & formattedValue.ToString.Trim, errorText, cellStyle, advancedBorderStyle, paintParts)
        CheckBoxRenderer.DrawCheckBox(graphics, New  Point(cellBounds.X + 6, 5), If(isChecked, VisualStyles.CheckBoxState.CheckedNormal, VisualStyles.CheckBoxState.UncheckedNormal))
    End Sub
  
    Protected Overrides  Sub OnMouseClick(ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
        If New  Rectangle(l, s).Contains(e.Location) Then
            isChecked = Not  isChecked
        End If
        MyBase.OnMouseClick(e)
    End Sub
End Class

  The Form Code

The checkHeaderCell Class is a fully reusable custom component. You just need to add the class to your project, and add one line of code to wire it up to your DataGridViewCheckBoxColumn.

In your Form code, you simply assign a HeaderCell:


Public Class  Form1
    Private Sub  Form1_Load(ByVal  sender As  System.Object, ByVal  e As  System.EventArgs) Handles MyBase.Load
        DataGridView1.Rows.Add(6)
        For r As Integer  = 0 To  5
            DataGridView1.Rows(r).SetValues(String.Format("R{0}C1", r), _
                                            String.Format("R{0}C2", r), _
                                            String.Format("R{0}C3", r), _
                                            False)
        Next
        DataGridView1.Columns(3).HeaderCell = New  checkHeaderCell
    End Sub
End Class

 


Other Resources