使用VB.NET开发WinForm程序时,使用DataGridView控件的时候经常需要在HeaderCell行头中显示行号,方便知道现在操作到哪一行了。笔者从网上收集了一些方法,并进行了测试。效果如图:
方法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
代码复制到自定义控件项里即可,如图:
方法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