60

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?

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
davioooh
  • 23,742
  • 39
  • 159
  • 250

13 Answers13

78

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);
}
vgru
  • 49,838
  • 16
  • 120
  • 201
Gabriel Perez
  • 781
  • 5
  • 2
63

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

row.HeaderCell.Value = String.Format("{0}", row.Index + 1);
LarsTech
  • 80,625
  • 14
  • 153
  • 225
mihZR
  • 696
  • 6
  • 5
  • 1
    Not sure everyone face this : I could not set value of HeaderCell before Form_Load() - that is in CTOR of the form. – Bharat Mori Jun 17 '16 at 18:24
12

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

Pat
  • 16,515
  • 15
  • 95
  • 114
Rob Sherratt
  • 121
  • 1
  • 4
  • 1
    This option also seems to have the distinct advantage of not automatically un-sharing the rows (vs. row.HeaderCell.Value, which does). Although it's otherwise very easy to un-share rows, it's advantageous for performance to try to preserve them where possible for large data sets according the [Documentation](https://msdn.microsoft.com/en-us/library/ha5xt0d9(v=vs.110).aspx). – Finch042 Jul 13 '15 at 10:37
  • Best answer so far. I tinkered with the formatting a bit. I changed to FontStyle.Regular, e.RowBounds.Top+3, e.RowBounds.Height-3, and SystemBrushes.InactiveCaptionText. It looks really good now. – D. Kermott Feb 09 '16 at 20:37
  • This doesn't take sorting into account. it will always start with 1,2,3.... Is there an option that keeps the 'original row number' even after column sorting? – John Grabanski Jan 22 '18 at 15:24
  • 1
    @JohnGrabanski Then it would not be a row number, it would be data associated with the row. For that, generally it would be better to add a column to hold that data. – John Oct 08 '20 at 03:12
12

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);
}
imsome1
  • 1,182
  • 4
  • 22
  • 37
sm.abdullah
  • 1,777
  • 1
  • 17
  • 34
9
private void setRowNumber(DataGridView dgv)
{
    foreach (DataGridViewRow row in dgv.Rows)
    {
        row.HeaderCell.Value = (row.Index + 1).ToString();
    }
}

This worked for me.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
timthez
  • 174
  • 1
  • 8
3

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

}
imsome1
  • 1,182
  • 4
  • 22
  • 37
Alireza815
  • 311
  • 3
  • 7
2

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();
}
FcoJavier99
  • 321
  • 2
  • 8
0

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();
    }
}
  • Bit late, but maybe it will help someone else. The solution it to set the DGV into virtual mode. https://msdn.microsoft.com/en-us/library/15a31akc(v=vs.110).aspx – MtnManChris Dec 27 '16 at 17:20
0
Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
        Dim rowIdx = (e.RowIndex + 1).ToString()
        Dim centerFormat = New StringFormat With {.Alignment = StringAlignment.Center, .LineAlignment = StringAlignment.Center}
        Dim textSize As Size = TextRenderer.MeasureText(rowIdx, sender.Font)
        If (sender.RowHeadersWidth < textSize.Width + 35) Then
            sender.RowHeadersWidth = textSize.Width + 35
        End If
        Dim headerBounds = New Rectangle(e.RowBounds.Left, e.RowBounds.Top, sender.RowHeadersWidth, e.RowBounds.Height)
        e.Graphics.DrawString(rowIdx, sender.Font, SystemBrushes.ControlText, headerBounds, centerFormat)
End Sub
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 13 '21 at 00:06
0

Simple way to count grid value just copy and paste your grid last

for (int i = 0; i < dgvStonesDetail.Rows.Count; i++) {
    dgvStonesDetail.Rows[counter].Cells[0].Value = (i + 1).ToString();
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
-1

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
-1

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;
    }
}
ArtEze
  • 186
  • 1
  • 5
  • 17
-1
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();
   }
}
M. Fawad Surosh
  • 450
  • 7
  • 20