VB.NET: DataGridView列头加checkbox 实现"全选"和"全不选"功能

时间:2022-01-14 10:36:32
以下方法在VBNET2008中通过验证:

a,新一个类库
b,类库属性应用程序类型更改为:Windows应用程序,启动窗体设置为DataGridViewCheckbox.Form1

下面为自定义类代码
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.Windows.forms
Namespace DataGridViewCheckBox

    Public Class Form1
        Inherits Form                            '继承于Form类
        Friend WithEvents Label1 As System.Windows.Forms.Label
        Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView
        
        Public Sub New()
            InitializeComponent()
        End Sub
        Private Sub InitializeComponent()
            Me.DataGridView1 = New System.Windows.Forms.DataGridView
            Me.Label1 = New System.Windows.Forms.Label
            CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'DataGridView1
            '
            Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
            Me.DataGridView1.Location = New System.Drawing.Point(12, 12)
            Me.DataGridView1.Name = "DataGridView1"
            Me.DataGridView1.RowTemplate.Height = 23
            Me.DataGridView1.Size = New System.Drawing.Size(457, 230)
            Me.DataGridView1.TabIndex = 0
            '
            'Label1
            '
            Me.Label1.AutoSize = True
            Me.Label1.Location = New System.Drawing.Point(10, 245)
            Me.Label1.Name = "Label1"
            Me.Label1.Size = New System.Drawing.Size(77, 12)
            Me.Label1.TabIndex = 1
            Me.Label1.Text = "点击列头选择"
            '
            'Form1
            '
            Me.ClientSize = New System.Drawing.Size(481, 265)
            Me.Controls.Add(Me.Label1)
            Me.Controls.Add(Me.DataGridView1)
            Me.Name = "Form1"
            CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)
            Me.PerformLayout()
        End Sub
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            DataGridViewCheckboxHeaderCellShow()
            Dim con As New SqlConnection("server=(local);uid=sa;pwd=sa;database=pubs")
            Dim cad As New SqlDataAdapter("select * from authors", con)
            Dim TAB As New DataSet
            cad.Fill(TAB)
            Me.DataGridView1.DataSource = TAB.Tables(0).DefaultView
            TAB.Dispose()
            cad.Dispose()
            con.Close()
            DataGridView1.AllowUserToAddRows = False                     '最下面的新行不显示
        End Sub

        Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick

            Me.Label1.Focus()
            Dim Click1 As DataGridCheckBoxHeaderCell.DataGridViewCheckBoxClickedHandler
            Click1 = New DataGridCheckBoxHeaderCell.DataGridViewCheckBoxClickedHandler(AddressOf Checkbox_OnCheckboxClicked)
            Click1.Invoke(True)
            REM   或    AddHandler DataGridCheckBoxHeaderCell.OnBooland, AddressOf Checkbox_OnCheckboxClicked
        End Sub
        Private Sub DataGridViewCheckboxHeaderCellShow()

            Dim checkbox1 As New DataGridCheckBoxHeaderCell            '定义一眉头Checkbox1从类DataGridCheckBoxHeaderCell构造而来
            Dim checkboxColumn As New DataGridViewCheckBoxColumn       '定义一个新列

            checkboxColumn.HeaderCell = checkbox1                      '新列增加一个控件Checkbox1
            checkboxColumn.HeaderCell.Value = "全选"                   '列头显示全选字符串
            Me.DataGridView1.Columns.Add(checkboxColumn)               'DataGridView1             新增0列并有checkbox属性
        End Sub

        Private Sub Checkbox_OnCheckboxClicked(ByVal ander As Boolean)

            For Each Row As DataGridViewRow In Me.DataGridView1.Rows
                If DataGridCheckBoxHeaderCell.IsChecked Then
                    Row.Cells(0).Value = True
                    Me.DataGridView1.Columns(0).HeaderText = "全不选"
                Else
                    Row.Cells(0).Value = False
                    Me.DataGridView1.Columns(0).HeaderText = "全选"
                End If
            Next
        End Sub
    End Class

    Public Class DataGridCheckBoxHeaderCellEventArgs
        Inherits EventArgs                                  '由 EventArgs继承
        Public Shared _bChecked As Boolean

        Public Sub New()
        End Sub

        Public Sub New(ByVal bChecked As Boolean)           '构造函数

            _bChecked = bChecked
        End Sub

        Protected Shared Shadows Property Checked() As Boolean
            Get
                If _bChecked = True Then _bChecked = True
                Return _bChecked
            End Get
            Set(ByVal value As Boolean)
                _bChecked = value
            End Set
        End Property

    End Class

    Public Class DataGridCheckBoxHeaderCell
        Inherits DataGridViewColumnHeaderCell                                                             'DataGridViewCheckBoxHeaderCell  由  DataGridViewColumnHeaderCell继承而来
        Public Delegate Sub DataGridViewCheckBoxClickedHandler(ByVal state As Boolean)                     ' 委托处理DataGridViewCheckBoxClickedHandler 事件
        Private checkBoxLocation As Point
        Public checkBoxSize As Size
        Public Shared _checked As Boolean
        Private _cellLocation As New Point()
        Private _cbState As System.Windows.Forms.VisualStyles.CheckBoxState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal
        Public Shared Event OnBooland(ByVal e As Boolean)
        Public Event OnCheckBoxClicked As DataGridViewCheckBoxClickedHandler

        REM   '重载重写DataGridvewOnCheckBoxClicked方法   由OnCheckBoxClicked引发  
        Protected Overridable Overloads Sub DataGridvewOnCheckBoxClicked(ByVal state As Boolean)
            RaiseEvent OnCheckBoxClicked(state)
            RaiseEvent OnBooland(_checked)
        End Sub

        REM  定义共享IsChecked属性
        Public Shared Property IsChecked() As Boolean
            Get
                Return _checked
            End Get
            Set(ByVal value As Boolean)
                _checked = value
                RaiseEvent OnBooland(_checked)
            End Set
        End Property
        '重写Paint方法
        Protected Overloads 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 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)

            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, System.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 = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal
            Else
                _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal
            End If
            CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState)
        End Sub

        REM   重写OnMouseClick方法  点击列头checkbox单击事件 
        Protected Overloads Overrides Sub OnMouseClick(ByVal e As DataGridViewCellMouseEventArgs)
            Dim p As New Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y)
            If p.X >= checkBoxLocation.X AndAlso p.X <= checkBoxLocation.X + checkBoxSize.Width AndAlso p.Y >= checkBoxLocation.Y AndAlso p.Y <= checkBoxLocation.Y + checkBoxSize.Height Then
                _checked = Not _checked
                DataGridvewOnCheckBoxClicked(_checked)
                Me.DataGridView.InvalidateCell(Me)
            End If
            MyBase.OnMouseClick(e)
        End Sub
    End Class
End Namespace

10 个解决方案

#1


接分~

#2


学习 学习

#3


循环赋值

#4


看不懂。绑定.

#5


代码太猥琐,死太多脑细胞

#6


也可以单独建一个类,然后引用这类。

#7


谢谢,VBNET也能实现全选功能,收藏了!

#8


引用 5 楼 cobra009 的回复:
代码太猥琐,死太多脑细胞

不会吧,就是重写一下类!

#9


对不起,我也是新手,如果我改写的类有看不懂的地方,请各位朋友谅解!

#10


包含了 InitializeComponent() 的完整代码。支持一下。

#1


接分~

#2


学习 学习

#3


循环赋值

#4


看不懂。绑定.

#5


代码太猥琐,死太多脑细胞

#6


也可以单独建一个类,然后引用这类。

#7


谢谢,VBNET也能实现全选功能,收藏了!

#8


引用 5 楼 cobra009 的回复:
代码太猥琐,死太多脑细胞

不会吧,就是重写一下类!

#9


对不起,我也是新手,如果我改写的类有看不懂的地方,请各位朋友谅解!

#10


包含了 InitializeComponent() 的完整代码。支持一下。