[c#] Show row number in row header of a DataGridView

Is it possible to show row number in the row header of a DataGridView?

I'm trying with this code, but it doesn't work:

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

Do I have to set some DataGridView property?

This question is related to c# .net winforms datagridview

The answer is


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);

}

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);
}

private void ShowRowNumber(DataGridView dataGridView)
{
   dataGridView.RowHeadersWidth = 50;
   for (int i = 0; i < dataGridView.Rows.Count; i++)
   {
        dataGridView.Rows[i].HeaderCell.Value = (i + 1).ToString();
   }
}

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();
    }
}

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

This worked for me.


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);
}

Based on this viedo: VB.net-Auto generate row number to datagridview in windows application-winforms, you can set the DataSource and this code puts the rows numbers, works like a charm.

private void DataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    // Add row number
    (sender as DataGridView).Rows[e.RowIndex].HeaderCell.Value = (e.RowIndex+1).ToString();
}

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


This worked for me.

Private Sub GridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles GridView1.CellFormatting
    Dim idx As Integer = e.RowIndex
    Dim row As DataGridViewRow = VDataGridView1.Rows(idx)
    Dim newNo As Long = idx
    If Not _RowNumberStartFromZero Then
        newNo += 1
    End If

    Dim oldNo As Long = -1
    If row.HeaderCell.Value IsNot Nothing Then
        If IsNumeric(row.HeaderCell.Value) Then
            oldNo = CLng(row.HeaderCell.Value)
        End If
    End If

    If newNo <> oldNo Then 'only change if it's wrong or not set
        row.HeaderCell.Value = newNo.ToString()
        row.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight
    End If
End Sub

This work in C#:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    int idx = e.RowIndex;
    DataGridViewRow row = dataGridView1.Rows[idx];
    long newNo = idx;
    if (!_RowNumberStartFromZero)
        newNo += 1;

    long oldNo = -1;
    if (row.HeaderCell.Value != null)
    {
        if (IsNumeric(row.HeaderCell.Value))
        {
            oldNo = System.Convert.ToInt64(row.HeaderCell.Value);
        }
    }

    if (newNo != oldNo)
    {
        row.HeaderCell.Value = newNo.ToString();
        row.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
    }
}

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to winforms

How to set combobox default value? Get the cell value of a GridView row Getting the first and last day of a month, using a given DateTime object Check if a record exists in the database Delete a row in DataGridView Control in VB.NET How to make picturebox transparent? Set default format of datetimepicker as dd-MM-yyyy Changing datagridview cell color based on condition C# Inserting Data from a form into an access Database How to use ConfigurationManager

Examples related to datagridview

How to refresh or show immediately in datagridview after inserting? Delete a row in DataGridView Control in VB.NET Looping each row in datagridview How to get cell value from DataGridView in VB.Net? Changing datagridview cell color based on condition Index was out of range. Must be non-negative and less than the size of the collection parameter name:index how to bind datatable to datagridview in c# DataGridView AutoFit and Fill How to export dataGridView data Instantly to Excel on button click? Populate a datagridview with sql query results