Mastering WPF DataGrid in a Day: Hour 7 Data Template

Before continuing this article, I highly recommend reading these previous parts:

Data Template

The DataGrid control not only displays data in a row and column format but it can also be used to display data in a templated format. The template is used to display a row data grouped into a template. You can define a data template as either XAML or as a resource. Imagine you need to display 50 fields in a DataGrid but a row can only display up to 10 columns. So how do you display more columns? You can use a DataTempate to do so.

If you look at Figure 13, you will see the DataGrid row has 5 columns but 3 additional columns are displayed as a part of the data template.


Figure 13

RowDetailsTemplate


The RowDetailsTemplate property represents the DataTemplate that is used to display a row details. The LoadingRowDetails and UnloadingRowDetails events are used to load and unload the data template or making changes.

A DataTemplate value is set as the RowDetailsTemplate of the DataGrid. The DataTemplate defines the vsual representation of all XAML elements of a row.

Listing 34 shows how to set the RowDetailsTemplate property of the DataGrid.

  1. <DataGrid x:Name="McDataGrid"   
  2.    <DataGrid.RowDetailsTemplate>  
  3.       <DataTemplate>  
  4.       </DataTemplate>  
  5.    </DataGrid.RowDetailsTemplate>              
  6. </DataGrid>  
Listing 34

Earlier in this chapter in Listing 3 the Author class is defined. Now, let's add three more properties to the Author class, City, Country and Zip. The new Author class is listed in Listing 35.
  1. public class Author  
  2. {  
  3.     public int ID { getset; }  
  4.     public string Name { getset; }  
  5.     public DateTime DOB { getset; }  
  6.     public string BookTitle { getset; }  
  7.     public bool IsMVP { getset; }        
  8.     public string Email { getset; }    
  9.     public string City { getset; }  
  10.     public string Country { getset; }  
  11.     public int Zip { getset; }  
  12. }  
Listing 35

Listing 36 is the new DataGrid XAML with a DataTemplate value.
  1. <DataGrid x:Name="McDataGrid" Margin="0" AutoGenerateColumns="False">  
  2.     <DataGrid.Columns>  
  3.         <DataGridTextColumn Binding="{Binding ID}" Header="Author ID" IsReadOnly="True"/>  
  4.         <DataGridTextColumn Header="Name" Width="140" Binding="{Binding Name}"  >  
  5.             <DataGridTextColumn.ElementStyle>  
  6.                 <Style TargetType="TextBlock">  
  7.                     <Setter Property="TextWrapping" Value="Wrap"/>  
  8.                 </Style>  
  9.             </DataGridTextColumn.ElementStyle>  
  10.             <DataGridTextColumn.EditingElementStyle>  
  11.                 <Style TargetType="TextBox">  
  12.                     <Setter Property="Foreground" Value="Blue"/>  
  13.                 </Style>  
  14.             </DataGridTextColumn.EditingElementStyle>  
  15.         </DataGridTextColumn>  
  16.   
  17.         <DataGridTemplateColumn Header="DOB"  Width="80">  
  18.             <DataGridTemplateColumn.CellTemplate>  
  19.                 <DataTemplate>  
  20.                     <TextBlock Text="{Binding DOB}" Margin="4"/>  
  21.                 </DataTemplate>  
  22.             </DataGridTemplateColumn.CellTemplate>  
  23.             <DataGridTemplateColumn.CellEditingTemplate>  
  24.                 <DataTemplate>  
  25.                     <DatePicker SelectedDate="{Binding DOB, Mode=TwoWay}" />  
  26.                 </DataTemplate>  
  27.             </DataGridTemplateColumn.CellEditingTemplate>  
  28.         </DataGridTemplateColumn>  
  29.   
  30.         <DataGridTextColumn Header="Book Title" Width="240" Binding="{Binding BookTitle}" >  
  31.             <DataGridTextColumn.ElementStyle>  
  32.                 <Style TargetType="TextBlock">  
  33.                     <Setter Property="TextWrapping" Value="Wrap"/>  
  34.                 </Style>  
  35.             </DataGridTextColumn.ElementStyle>  
  36.             <DataGridTextColumn.EditingElementStyle>  
  37.                 <Style TargetType="TextBox">  
  38.                     <Setter Property="Foreground" Value="Blue"/>  
  39.                 </Style>  
  40.             </DataGridTextColumn.EditingElementStyle>  
  41.         </DataGridTextColumn>  
  42.         <DataGridCheckBoxColumn Header="MVP" Binding="{Binding IsMVP}" IsThreeState="True" />  
  43.     </DataGrid.Columns>  
  44.   
  45.     <DataGrid.RowDetailsTemplate>  
  46.         <DataTemplate>  
  47.             <Border BorderThickness="0" Background="Beige" Padding="10">  
  48.                         <Grid Margin="5,0,0,0" MinWidth="650" HorizontalAlignment="Left">  
  49.                             <Grid.ColumnDefinitions>  
  50.                                 <ColumnDefinition Width="125"></ColumnDefinition>  
  51.                                 <ColumnDefinition Width="*"></ColumnDefinition>  
  52.                                 <ColumnDefinition Width="125"></ColumnDefinition>  
  53.                                 <ColumnDefinition Width="*"></ColumnDefinition>  
  54.                             </Grid.ColumnDefinitions>  
  55.                             <Grid.RowDefinitions>  
  56.                                 <RowDefinition Height="Auto"></RowDefinition>  
  57.                                 <RowDefinition Height="Auto"></RowDefinition>  
  58.                                 <RowDefinition Height="Auto"></RowDefinition>  
  59.                                 <RowDefinition Height="Auto"></RowDefinition>  
  60.                             </Grid.RowDefinitions>  
  61.   
  62.                             <TextBlock Text="City" Margin="10,0,0,0" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left"/>  
  63.                             <TextBox Margin="3" Grid.Row="0" Grid.Column="1" Text="{Binding Path=City}" MaxHeight="35" />  
  64.                             <TextBlock Text="Country" Margin="10,0,0,0" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />  
  65.                             <TextBox Margin="3" Grid.Row="1" Grid.Column="1" Text="{Binding Path=Country}" MaxHeight="35"/>  
  66.                             <TextBlock Text="Zip" Margin="10,0,0,0" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center"  HorizontalAlignment="Left"/>  
  67.                             <TextBox Margin="3" Grid.Row="2" Grid.Column="1" Text="{Binding Path=Zip}" MaxHeight="35"/>  
  68.                         </Grid>  
  69.                     </Border>  
  70.         </DataTemplate>  
  71.     </DataGrid.RowDetailsTemplate>  
  72. </DataGrid>      
Listing 36

The new AuthorCollection with updated Author objects is listed in Listing 37.
  1. public class AuthorCollection : CollectionBase  
  2. {  
  3.     /// <summary>  
  4.     /// List of Authors  
  5.     /// </summary>  
  6.     /// <returns></returns>  
  7.     public List<Author> LoadAuthors()  
  8.     {  
  9.         List<Author> authors = new List<Author>();  
  10.             authors.Add(new Author() { ID = 101, Name = "Mahesh Chand",  
  11.                 BookTitle = "Graphics Programming with GDI+",  
  12.                 DOB = new DateTime(1975, 2, 23), IsMVP = false,  
  13.                 City = "Philadelphia", Country="USA", Zip = 19060  
  14.         });  
  15.         authors.Add(new Author()  
  16.         {  
  17.             ID = 201, Name = "Mike Gold",  
  18.             BookTitle = "Programming C#",  
  19.             DOB = new DateTime(1982, 4, 12), IsMVP = true,  
  20.             City = "Austin",  
  21.             Country = "USA", Zip = 23020  
  22.         });  
  23.         authors.Add(new Author()  
  24.         {  
  25.             ID = 244, Name = "Praveen Kumar",  
  26.             BookTitle = "ADO.NET Development",  
  27.             DOB = new DateTime(1985, 9, 11), IsMVP = true,  
  28.             City = "New Delhi",  
  29.             Country = "India", Zip = 201301  
  30.         });  
  31.              
  32.             return authors;  
  33.     }  
  34. }  
Listing 37

Now build and run the project. When you click on a row, the additional Author properties are listed below the row. See Figure 14.


Figure 14

Get Selected Items


The SelectedItems property returns all selected items in a DataGrid. Each selected item represents an object bound to a row. For example, in our case, an Author object and its properties are bound to the DataGrid rows.

The code snippet in Listing 38 uses the DataGrid.SelectedItems property and displays a number of selected items and then displays the Name column values of the selected items.
  1. var AuthorInfo = new System.Text.StringBuilder();  
  2. MessageBox.Show(McDataGrid.SelectedItems.Count.ToString() + "items selected.");  
  3.   
  4. foreach (Author author in McDataGrid.SelectedItems)  
  5. {  
  6.     AuthorInfo.AppendLine(author.Name);  
  7. }  
  8. MessageBox.Show(AuthorInfo.ToString());  
Listing 38

Summary

In this article of the Mastering WPF DataGrid series, we saw how to use a DataTemplate to format a DataGrid row data.

In the next and final article of this series, I will discuss how to implement CRUD functionality in a DataGrid.

<<Previous Article                                         Next Article>>


Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.