Simple way to display row numbers on WPF DataGrid

One way is to add them in the LoadingRow event for the DataGrid

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()).ToString(); 
}

When items are added or removed from the source list then the numbers can get out of sync for a while. For a fix to this, see the attached behavior here:
WPF 4 DataGrid: Getting the Row Number into the RowHeader

Useable like this

<DataGrid ItemsSource="{Binding ...}"
          behaviors:DataGridBehavior.DisplayRowNumber="True"> 

If your data grid has its ItemsSource bound to a collection, bind the AlternationCount property of your data grid to either the the count property of your collection, or to the Items.Count property of your DataGrid as follows:

<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding MyObservableCollection.Count}" />

Or:

<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}" />

Either should work.

Then, assuming you're using a DataGridTextColumn for your leftmost column you do the following in your DataGrid.Columns definition:

<DataGrid.Columns>
   <DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}"
</DataGrid.Columns>

If you don't want to start at 0, you can add a converter to your binding to increment the index.


It's an old question, but I would like to share something. I had a similar problem, all I needed was a simple RowHeader numeration of rows and Fredrik Hedblad's answer was almost complete for my problem.

While this is great:

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()).ToString(); 
}

my headers messed up when removing and adding items. If you have buttons responsible for that just add dataGrid.Items.Refresh(); under the 'deleting' code as in my case:

private void removeButton_Click(object sender, RoutedEventArgs e)
{
    // delete items

    dataGrid.Items.Refresh();
}

That solved desyncronized numeration for me, because refreshing items calls DataGrig_LoadingRow again.


Adding a short info about Fredrik Hedblad answer.

<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex()+1).ToString(); 
}

...If you want to start numbering from 1