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