How to: Add Row Details to a DataGrid Control

When using the DataGrid control, you can customize the data presentation by adding a row details section. Adding a row details section enables you to group some data in a template that is optionally visible or collapsed. For example, you can add row details to a DataGrid that presents only a summary of the data for each row in the DataGrid, but presents more data fields when the user selects a row. You define the template for the row details section in the RowDetailsTemplate property. The following illustration shows an example of a row details section.

DataGrid shown with row details

You define the row details template as either inline XAML or as a resource. Both approaches are shown in the following procedures. A data template that is added as a resource can be used throughout the project without re-creating the template. A data template that is added as inline XAML is only accessible from the control where it is defined.

To display row details by using inline XAML

  1. Create a DataGrid that displays data from a data source.

  2. In the DataGrid element, add a RowDetailsTemplate element.

  3. Create a DataTemplate that defines the appearance of the row details section.

    The following XAML shows the DataGrid and how to define the RowDetailsTemplate inline. The DataGrid displays three values in each row and three more values when the row is selected.

    <Window x:Class="WpfApplication1.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" 
            Loaded="Window_Loaded">
        <Grid>
            <DataGrid Name="dataGrid1" IsReadOnly="True" AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Company Name" Binding="{Binding CompanyName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Contact First Name" Binding="{Binding FirstName}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Contact Last Name" Binding="{Binding LastName}"></DataGridTextColumn>
                </DataGrid.Columns>
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
                            <StackPanel Orientation="Vertical">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock FontSize="12" Text="Email: " VerticalAlignment="Center" />
                                    <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding EmailAddress}" VerticalAlignment="Center" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock FontSize="12" Text="Phone: " VerticalAlignment="Center" />
                                    <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding Phone}" VerticalAlignment="Center" />
                                </StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock FontSize="12" Text="Sales Person: " VerticalAlignment="Center" />
                                    <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding SalesPerson}" VerticalAlignment="Center" />
                                </StackPanel>
                            </StackPanel>
                        </Border>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
        </Grid>
    </Window>
    

    The following code shows the query that is used to select the data that is displayed in the DataGrid. In this example, the query selects data from an entity that contains customer information.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        AdventureWorksLT2008Entities advenWorksEntities = new AdventureWorksLT2008Entities();
    
        ObjectQuery<Customer> customers = advenWorksEntities.Customers;
    
        var query =
        from customer in customers
        orderby customer.CompanyName
        select new
        {
            customer.LastName,
            customer.FirstName,
            customer.CompanyName,
            customer.Title,
            customer.EmailAddress,
            customer.Phone,
            customer.SalesPerson
        };
    
        dataGrid1.ItemsSource = query.ToList();
    }
    
    Dim advenWorksEntities As AdventureWorksLT2008Entities = New AdventureWorksLT2008Entities
    
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Dim customers As ObjectQuery(Of Customer) = advenWorksEntities.Customers
        Dim query = _
            From customer In customers _
            Order By customer.CompanyName _
            Select _
              customer.LastName, _
              customer.FirstName, _
              customer.CompanyName, _
              customer.Title, _
              customer.EmailAddress, _
              customer.Phone, _
              customer.SalesPerson
    
        dataGrid1.ItemsSource = query.ToList()
    End Sub
    

To display row details by using a resource

  1. Create a DataGrid that displays data from a data source.

  2. Add a Resources element to the root element, such as a Window control or a Page control, or add a Resources element to the Application class in the App.xaml (or Application.xaml) file.

  3. In the resources element, create a DataTemplate that defines the appearance of the row details section.

    The following XAML shows the RowDetailsTemplate defined in the Application class.

    <Application.Resources>
        <DataTemplate x:Key="CustomerDetail">
            <Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
                <StackPanel Orientation="Vertical">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="12" Text="Email: " VerticalAlignment="Center" />
                        <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding EmailAddress}" VerticalAlignment="Center" />
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="12" Text="Phone: " VerticalAlignment="Center" />
                        <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding Phone}" VerticalAlignment="Center" />
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="12" Text="Sales Person: " VerticalAlignment="Center" />
                        <TextBlock FontSize="16" Foreground="MidnightBlue" Text="{Binding SalesPerson}" VerticalAlignment="Center" />
                    </StackPanel>
                </StackPanel>
            </Border>
        </DataTemplate>
    </Application.Resources>
    
  4. On the DataTemplate, set the x:Key Directive to a value that uniquely identifies the data template.

  5. In the DataGrid element, set the RowDetailsTemplate property to the resource defined in the previous steps. Assign the resource as a static resource.

    The following XAML shows the RowDetailsTemplate property set to the resource from the previous example.

    <DataGrid Name="dataGrid1" IsReadOnly="True" AutoGenerateColumns="False" RowDetailsTemplate="{StaticResource CustomerDetail}" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Company Name" Binding="{Binding CompanyName}"></DataGridTextColumn>
            <DataGridTextColumn Header="Contact First Name" Binding="{Binding FirstName}"></DataGridTextColumn>
            <DataGridTextColumn Header="Contact Last Name" Binding="{Binding LastName}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
    

To set visibility and prevent horizontal scrolling for row details

  1. If needed, set the RowDetailsVisibilityMode property to a DataGridRowDetailsVisibilityMode value.

    By default, the value is set to VisibleWhenSelected. You can set it to Visible to show the details for all of the rows or Collapsed to hide the details for all rows.

  2. If needed, set the AreRowDetailsFrozen property to true to prevent the row details section from scrolling horizontally.