[VB.NET] Hướng dẫn chọn nhiều dòng trên Datagridview

[VB.NET] Hướng dẫn chọn nhiều dòng trên Datagridview
Đăng bởi: Thảo Meo - Lượt xem: 125 08:26:20, 15/02/2025VB.NET   In bài viết

Xin chào các bạn, bài viết hôm nay mình tiếp tục hướng dẫn các bạn các chọn nhiều dòng trên Datagridview vb.net winform.

[VB.NET] Chọn nhiều dòng trên lưới DataGridview

Trên Datagridview của winform, nó không có hỗ trợ cho chúng ta, tạo checkbox để có thể chọn nhiều dòng, hoặc click để chọn tất cả.

Bài viết này, sẽ giúp các bạn thực hiện công việc này.

Dưới đây, là video demo ứng dụng:

Đầu tiên, các bạn tạo một component SelectAllGridView.vb nội dung như sau:

Imports System
Imports System.Data
Imports System.Windows.Forms
Imports System.ComponentModel

Public Class SelectAllGridView
    Inherits DataGridView

    Private TotalCheckBoxes As Integer = 0
    Private TotalCheckedCheckBoxes As Integer = 0
    Private HeaderCheckBox As CheckBox = Nothing
    Private IsHeaderCheckBoxClicked As Boolean = False
    Private CheckBoxColumn As DataGridViewCheckBoxColumn

    Public Event SelectionChanged As EventHandler

    Public Sub New()
        InitializeGrid()
    End Sub

    Private Sub InitializeGrid()
        CheckBoxColumn = New DataGridViewCheckBoxColumn() With {
            .HeaderText = "",
            .Name = "chkBxSelect",
            .Width = 30,
            .AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        }

        ' Add checkbox column to grid
        Me.Columns.Add(CheckBoxColumn) ' Use Add instead of Insert to avoid index issues

        ' Create header checkbox
        HeaderCheckBox = New CheckBox With {
            .Size = New Size(15, 15)
        }

        Me.Controls.Add(HeaderCheckBox)

        ' Add event handlers
        AddHandler HeaderCheckBox.KeyUp, AddressOf HeaderCheckBox_KeyUp
        AddHandler HeaderCheckBox.MouseClick, AddressOf HeaderCheckBox_MouseClick
        AddHandler Me.CellValueChanged, AddressOf Grid_CellValueChanged
        AddHandler Me.CurrentCellDirtyStateChanged, AddressOf Grid_CurrentCellDirtyStateChanged
        AddHandler Me.CellPainting, AddressOf Grid_CellPainting
    End Sub

    ' Get selected items
    Public Function GetSelectedItems() As DataTable
        Dim sourceTable As DataTable = CType(Me.DataSource, DataTable)
        Dim selectedData As DataTable = sourceTable.Clone()

        For Each row As DataGridViewRow In Me.Rows
            If Convert.ToBoolean(row.Cells("chkBxSelect").Value) Then
                Dim newRow As DataRow = selectedData.NewRow()
                For Each col As DataColumn In sourceTable.Columns
                    Try
                        Dim cellValue = row.Cells(col.ColumnName).Value
                        newRow(col.ColumnName) = If(cellValue Is Nothing, DBNull.Value, cellValue)
                    Catch ex As Exception
                        Continue For
                    End Try
                Next
                selectedData.Rows.Add(newRow)
            End If
        Next

        Return selectedData
    End Function

    ' Set DataSource with checkbox column
    Public Shadows Sub SetDataSource(ByVal dataTable As DataTable)
        Me.DataSource = Nothing

        ' Clone the original table and remove the checkbox column if it exists
        Dim newTable As DataTable = dataTable.Copy()
        If newTable.Columns.Contains("chkBxSelect") Then
            newTable.Columns.Remove("chkBxSelect")
        End If

        ' Disable auto-generation to prevent duplicate columns
        Me.AutoGenerateColumns = False
        Me.DataSource = newTable
        Me.AutoGenerateColumns = True ' Re-enable if needed for other columns

        TotalCheckBoxes = Me.RowCount
        TotalCheckedCheckBoxes = 0
    End Sub

    Private Sub HeaderCheckBox_MouseClick(sender As Object, e As MouseEventArgs)
        HeaderCheckBoxClick(CType(sender, CheckBox))
    End Sub

    Private Sub HeaderCheckBox_KeyUp(sender As Object, e As KeyEventArgs)
        If e.KeyCode = Keys.Space Then HeaderCheckBoxClick(CType(sender, CheckBox))
    End Sub

    Private Sub Grid_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
        If Not IsHeaderCheckBoxClicked AndAlso e.ColumnIndex = 0 Then
            RowCheckBoxClick(CType(Me(e.ColumnIndex, e.RowIndex), DataGridViewCheckBoxCell))
            RaiseEvent SelectionChanged(Me, EventArgs.Empty)
        End If
    End Sub

    Private Sub Grid_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs)
        If TypeOf Me.CurrentCell Is DataGridViewCheckBoxCell Then
            Me.CommitEdit(DataGridViewDataErrorContexts.Commit)
        End If
    End Sub

    Private Sub Grid_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs)
        If e.RowIndex = -1 AndAlso e.ColumnIndex = 0 Then
            ResetHeaderCheckBoxLocation(e.ColumnIndex, e.RowIndex)
        End If
    End Sub

    Private Sub ResetHeaderCheckBoxLocation(ColumnIndex As Integer, RowIndex As Integer)
        Dim headerRect = Me.GetCellDisplayRectangle(ColumnIndex, RowIndex, True)

        Dim point As Point = New Point()
        point.X = headerRect.Location.X + (headerRect.Width - HeaderCheckBox.Width) \ 2 + 1
        point.Y = headerRect.Location.Y + (headerRect.Height - HeaderCheckBox.Height) \ 2 + 1

        HeaderCheckBox.Location = point
    End Sub

    Private Sub HeaderCheckBoxClick(headerCheckBox As CheckBox)
        IsHeaderCheckBoxClicked = True

        For Each row As DataGridViewRow In Me.Rows
            CType(row.Cells("chkBxSelect"), DataGridViewCheckBoxCell).Value = headerCheckBox.Checked
        Next

        Me.RefreshEdit()

        TotalCheckedCheckBoxes = If(headerCheckBox.Checked, TotalCheckBoxes, 0)
        IsHeaderCheckBoxClicked = False

        RaiseEvent SelectionChanged(Me, EventArgs.Empty)
    End Sub

    Private Sub RowCheckBoxClick(checkBox As DataGridViewCheckBoxCell)
        If checkBox IsNot Nothing Then
            If CBool(checkBox.Value) AndAlso TotalCheckedCheckBoxes < TotalCheckBoxes Then
                TotalCheckedCheckBoxes += 1
            ElseIf TotalCheckedCheckBoxes > 0 Then
                TotalCheckedCheckBoxes -= 1
            End If

            HeaderCheckBox.Checked = (TotalCheckedCheckBoxes = TotalCheckBoxes)
        End If
    End Sub
End Class

Và ở form1.vb sử dụng, các bạn chỉ cần set datasource là xong.

Public Class Form1
    Private Sub LoadData()
        Dim dt As New DataTable()
        dt.Columns.Add("ID", GetType(Integer))
        dt.Columns.Add("Name", GetType(String))

        For i As Integer = 1 To 10
            dt.Rows.Add(i, "Row " & i)
        Next


        SelectAllGridView2.SetDataSource(dt)
    End Sub


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        LoadData()
    End Sub



    Private Sub btnShowSelected_Click(sender As Object, e As EventArgs) Handles btnShowSelected.Click
        Dim selectedItems As DataTable = SelectAllGridView2.GetSelectedItems()

        TextBox1.Text = ""

        For Each row As DataRow In selectedItems.Rows
            TextBox1.Text += ($"Selected: {row("Name")} " + Environment.NewLine)
        Next
    End Sub
End Class

Thanks for watching!

DOWNLOAD SOURCE

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[VB.NET] Hướng dẫn chọn nhiều dòng trên Datagridview
Đăng bởi: Thảo Meo - Lượt xem: 125 08:26:20, 15/02/2025VB.NET   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp