BLOG main image
분류 전체보기 (313)
교육 (13)
NEIS (6)
Edufine (0)
Programmer (5)
Android Programming (1)
Internet W3 (18)
JAVA Programming (9)
JSP/Servlet (1)
Framework (7)
Spring For Beginner (4)
eGovFrame (10)
MEAN Stack (2)
NodeJS (5)
SublimeText (30)
SublimeText_Tips (18)
Eclipse (16)
JavaScript (8)
jQuery (12)
jQuery_tips (1)
Ajax (3)
DWR(Direct Web Remote) (4)
JSON(JS Object Notation) (4)
Oracle (2)
MySQL (28)
OS (16)
Download (3)
Life (10)
Favorit Site (1)
Books (2)
Healthy (1)
Stocks (1)
HTML5/CSS (1)
Python (4)
Security (7)
CISSP (0)
Ruby On Rails (5)
일기장 (0)
영어 교과서(중2) (3)
알고리즘 (0)
Go Lang (3)
VB 2010 (12)
C# (1)
정보보안기사(네트워크보안) (0)
업무 활용 엑셀 (11)
틈틈이 활용팁 (14)
하루 하루 살아가며 ……. (2)
기술 (1)
파이썬 & 데이터분석 (1)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
2016. 4. 24. 16:54

CheckBox in Header Cell of DataGridView Control

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!Smile

 

https://pradeep1210.wordpress.com/2012/05/16/checkbox-in-header-cell-of-datagridview-control/

 

반응형

'VB 2010' 카테고리의 다른 글

수당 정리  (0) 2016.05.06
Visual Studio SP 다운경로  (0) 2016.04.25
20160414_코딩 도움 사이트  (0) 2016.04.14
[VB.NET] DataGridView 팁 정리  (0) 2016.04.14
Visual Basic 2010 참고사이트  (0) 2016.04.07