Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show row number in row header of a DataGridView

You can also draw the string dynamically inside the RowPostPaint event:

private void dgGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    var grid = sender as DataGridView;
    var rowIdx = (e.RowIndex + 1).ToString();

    var centerFormat = new StringFormat() 
    { 
        // right alignment might actually make more sense for numbers
        Alignment = StringAlignment.Center, 
        LineAlignment = StringAlignment.Center
    };

    var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
    e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}

It seems that it doesn't turn it into a string. Try

row.HeaderCell.Value = String.Format("{0}", row.Index + 1);

Thanks @Gabriel-Perez and @Groo, great idea! In case others want it, here's a version in VB tested in Visual Studio 2012. In my case I wanted the numbers to appear top right aligned in the Row Header.

Private Sub MyDGV_RowPostPaint(sender As Object, _
    e As DataGridViewRowPostPaintEventArgs) Handles MyDataGridView.RowPostPaint

    ' Automatically maintains a Row Header Index Number 
    '   like the Excel row number, independent of sort order

    Dim grid As DataGridView = CType(sender, DataGridView)
    Dim rowIdx As String = (e.RowIndex + 1).ToString()
    Dim rowFont As New System.Drawing.Font("Tahoma", 8.0!, _
        System.Drawing.FontStyle.Bold, _
        System.Drawing.GraphicsUnit.Point, CType(0, Byte))

    Dim centerFormat = New StringFormat()
    centerFormat.Alignment = StringAlignment.Far
    centerFormat.LineAlignment = StringAlignment.Near

    Dim headerBounds As Rectangle = New Rectangle(_
        e.RowBounds.Left, e.RowBounds.Top, _
        grid.RowHeadersWidth, e.RowBounds.Height)
    e.Graphics.DrawString(rowIdx, rowFont, SystemBrushes.ControlText, _
        headerBounds, centerFormat)
End Sub

You can also get the default font, rowFont = grid.RowHeadersDefaultCellStyle.Font, but it might not look as good. The screenshot below is using the Tahoma font.

Example on windows 7


private void setRowNumber(DataGridView dgv)
{
    foreach (DataGridViewRow row in dgv.Rows)
    {
        row.HeaderCell.Value = (row.Index + 1).ToString();
    }
}

This worked for me.


just enhancing above solution.. so header it self resize its width in order to accommodate lengthy string like 12345

private void advancedDataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    var grid = sender as DataGridView;
    var rowIdx = (e.RowIndex + 1).ToString();

    var centerFormat = new StringFormat()
    {
        // right alignment might actually make more sense for numbers
        Alignment = StringAlignment.Center,

        LineAlignment = StringAlignment.Center
    };
    //get the size of the string
    Size textSize = TextRenderer.MeasureText(rowIdx, this.Font);
    //if header width lower then string width then resize
    if (grid.RowHeadersWidth < textSize.Width + 40)
    {
        grid.RowHeadersWidth = textSize.Width + 40;
    }
    var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
    e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}

you can do this :

private void setRowNumber(DataGridView dgv)
{
    foreach (DataGridViewRow row in dgv.Rows)
    {
        row.HeaderCell.Value = row.Index + 1;
    }

    dgv.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);

}

row.HeaderCell.Value = row.Index + 1;

when applied on datagridview with a very large number of rows creates a memory leak and eventually will result in an out of memory issue. Any ideas how to reclaim the memory?

Here is sample code to apply to an empty grid with some columns. it simply adds rows and numbers the index. Repeat button click a few times.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        dataGridView1.SuspendLayout();
        for (int i = 1; i < 10000; i++)
        {
            dataGridView1.Rows.Add(i);                
        }
        dataGridView1.ResumeLayout();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        foreach (DataGridViewRow row in dataGridView1.Rows)
            row.HeaderCell.Value = (row.Index + 1).ToString();
    }
}