WPF DataGrid Tutorial – Row Headers

When using Data Grids to present data, row headers can be valuable additions – especially if the grid contains more columns than can fit on the screen at one time. Row headers don’t scroll horizontally with the rest of the content, which means users can use them to see the context of the data they’re viewing. This tutorial will demonstrate how to create row headers using WPF’s DataGrid control.

The first thing we need is some data to put in our DataGrid. I’m going to use a very basic Movie class that contains some basic information about movies for this.

/// <summary>
/// Class that holds basic details for a movie.
/// </summary>
public class Movie
{
  public string Title { get; set; }
  public int Year { get; set; }
  public string Director { get; set; }
}

Now let’s create some of these and assign them to the DataGrid’s ItemsSource.

// Create a collection of movies.
var movies = new List<Movie>
{
  new Movie()
  {
    Title = "The Fifth Element",
    Year = 1997,
    Director = "Luc Besson"
  },

  new Movie()
  {
    Title = "Dark City",
    Year = 1998,
    Director = "Alex Proyas"
  },

  new Movie()
  {
    Title = "The Lawnmower Man",
    Year = 1992,
    Director = "Brett Leonard"
  }
};

// Fill the datagrid with the collection of movies.
// This datagrid is defined in XAML.
_myDataGrid.ItemsSource = movies;

In this snippet of code, I’ve created three Movie objects and put them into a List. I then assigned the list to the ItemsSource of a DataGrid. The DataGrid was created in XAML, so let’s look at that now.

<Window x:Class="DataGridRowHeader.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="MainWindow"
       Height="350"
       Width="525">
  <Grid>
    <DataGrid x:Name="_myDataGrid"
             AutoGenerateColumns="False"
             IsReadOnly="True">
      <DataGrid.Columns>
        <DataGridTextColumn Header="Title"
                           Binding="{Binding Title}" />
        <DataGridTextColumn Header="Year"
                           Binding="{Binding Year}" />
        <DataGridTextColumn Header="Director"
                           Binding="{Binding Director}" />
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</Window>

If we run this code now, we’d get something that looks like this:

No row headers

Obviously we have no row headers yet. Let’s take a look at the XAML change required to make those happen.

<DataGrid x:Name="_myDataGrid"
         AutoGenerateColumns="False"
         IsReadOnly="True">
  <DataGrid.RowHeaderStyle>
    <Style TargetType="DataGridRowHeader">
      <Setter Property="Content"
             Value="{Binding Title}" />
    </Style>
  </DataGrid.RowHeaderStyle>
  <DataGrid.Columns>
    <DataGridTextColumn Header="Year"
                       Binding="{Binding Year}" />
    <DataGridTextColumn Header="Director"
                       Binding="{Binding Director}" />
  </DataGrid.Columns>
</DataGrid>

Unfortunately, row headers aren’t as simple as they should be to set up, but they’re not too bad once you’ve figured it out. What we have to do is use a style to set the Content property of the DataGridRowHeader objects. The DataGrid directly exposes a property that can be used to set this style – which is nice. What we’re doing is setting the content to a property in our Movie class, the Title. Since the title is now in the row header, I also removed the column for this property. Now if we run the app, we get something that looks like this:

Row headers

And there you have it. We’ve created nice looking row headers for our WPF DataGrid. Hopefully this helped you out in your own projects, and if you have any questions or comments, feel free to leave them below.

Leave a Reply

Your email address will not be published. Required fields are marked *