VB.NET学习笔记:扩展 DataGridView 的功能——在HeaderCell中显示行号方法集锦

使用VB.NET开发WinForm程序时,使用DataGridView控件的时候经常需要在HeaderCell行头中显示行号,方便知道现在操作到哪一行了。笔者从网上收集了一些方法,并进行了测试。效果如图:
显示行号

一、使用DataGridView控件的相关事件

方法1:

Private Sub DataGridView1_RowStateChanged(sender As Object, e As DataGridViewRowStateChangedEventArgs) Handles DataGridView1.RowStateChanged
        For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
            Me.DataGridView1.Rows(i).HeaderCell.Value = String.Format("{0}", i + 1)
        Next

        Me.DataGridView1.Refresh()
    End Sub

当滚动DataGridView控件时闪烁厉害,行号显示不全(解决办法是将DataGridView控件的RowHeadersWidthSizeMode属性设置为AutoSizeToAllHeaders、AutoSizeToDisplayedHeaders或者AutoSizeToFirstHeader,如图)。
自动调整行头列宽
方法2:

Private Sub DataGridView1_RowStateChanged(sender As Object, e As DataGridViewRowStateChangedEventArgs) Handles DataGridView1.RowStateChanged
        e.Row.HeaderCell.Value = (e.Row.Index + 1).ToString
    End Sub

这个方法对于DataGridView控件设置成只读属性的话很实用,速度快。如果要删除行的话,就会出现行号跳耀,如图:
在这里插入图片描述
方法3:

Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
        Dim rectangle As Rectangle = New Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, DataGridView1.RowHeadersWidth - 4, e.RowBounds.Height)
        TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), DataGridView1.RowHeadersDefaultCellStyle.Font, rectangle, DataGridView1.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.Right)
    End Sub

方法4:

Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
        Dim grid As DataGridView = TryCast(sender, DataGridView)
        Dim rowIdx As String = (e.RowIndex + 1).ToString()
        Dim centerFormat As StringFormat = New StringFormat() With {
            .Alignment = StringAlignment.Center,
            .LineAlignment = StringAlignment.Center
        }
        Dim headerBounds As Rectangle = New Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height)
        e.Graphics.DrawString(rowIdx, Me.Font, SystemBrushes.ControlText, headerBounds, centerFormat)
    End Sub

方法5:

Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
        If e.ColumnIndex = -1 AndAlso e.RowIndex >= 0 AndAlso e.RowIndex < DataGridView1.Rows.Count Then
            e.PaintBackground(e.ClipBounds, True)
            e.Graphics.DrawString((e.RowIndex + 1).ToString(), Font, Brushes.Black, e.CellBounds.Left + 6, e.CellBounds.Top + 5)
            e.Handled = True
        End If
    End Sub

二、继承DataGridView扩展为自定义控件

代码复制到自定义控件项里即可,如图:
在这里插入图片描述
方法6:

Public Class DataGridViewExi
    Inherits DataGridView

    Private _showRowHeaderNumbers As Boolean

    <Category("扩展属性"), Description("是否显示行号"), DefaultValue(False)>
    Public Property ShowRowHeaderNumbers As Boolean
        Get
            Return _showRowHeaderNumbers
        End Get
        Set(ByVal value As Boolean)
            If _showRowHeaderNumbers <> value Then Invalidate()
            _showRowHeaderNumbers = value
        End Set
    End Property

    Public Sub New()
        InitializeComponent()
    End Sub

    Protected Overrides Sub OnRowPostPaint(ByVal e As DataGridViewRowPostPaintEventArgs)
        If _showRowHeaderNumbers Then
            Dim title As String = (e.RowIndex + 1).ToString()
            Dim brush As Brush = Brushes.Black
            e.Graphics.DrawString(title, DefaultCellStyle.Font, brush, CType(e.RowBounds.Location.X + RowHeadersWidth / 2 - 4, Single), CType(e.RowBounds.Location.Y + 4, Single))
        End If

        MyBase.OnRowPostPaint(e)
    End Sub
End Class

方法7:

Public Class DataGridViewEx
    Inherits DataGridView

    Public Sub New()
        MyBase.New()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw, True)
        Me.RowTemplate.HeaderCell = New DataGridViewRowHeaderCellEx()
    End Sub
End Class

Public Class DataGridViewRowHeaderCellEx
    Inherits DataGridViewRowHeaderCell

    Public Sub New()
        MyBase.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 cellState 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, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
        TextRenderer.DrawText(graphics, (rowIndex + 1).ToString(), DataGridView.Font, cellBounds, Color.Black)
    End Sub
End Class