Content Template And Data Template In WPF

Templates in WPF are used to customize the UI. We can manipulate both controls as well as data.
 
Every control in WPF has its default template associated with it. Default template defines a look and feel, basically a style of control.
 
That's why by default, Button or TextBox shapes are ectangular because it is defined in its default template. Now we can update that template and add our own implementation.
 
In WPF there are 2 types of Templates,
  1. Control Template: Customize the appearance
  2. Data Template: Customize the functionality.
Note
We can define these templates inside App.xaml or in Resource file to reuse them in the application.

Control Template

 
So by default, this is how the Button looks.
  1. <Button x:Name="SubmitButton"    
  2.              Content="Submit"    
  3.              Height="20"    
  4.              Width="100"/>     
Content Template And Data Template In WPF 
 
Let's create a custom control to change the shape of this button.

Let's add a ControlTemplate inside a Button to achieve this. But you might get the following error.
 
Content Template And Data Template In WPF
 
As you can see .net framework is giving us compiled time error, specifying Visual tree can only be set once, meaning that ControlTemplate can only have
one child. But we have a couple of tags inside a ControlTemplate.
  1. <Button x:Name="SubmitButton"    
  2.              Content="Submit"    
  3.              Height="20"    
  4.              Width="100">    
  5.           <Button.Template>    
  6.               <ControlTemplate>    
  7.                   <Ellipse Fill="Gray"/>    
  8.                   <ContentPresenter/>    
  9.               </ControlTemplate>    
  10.           </Button.Template>    
  11. </Button>     
So to overcome this problem, we can add Panel inside ControlTemplate and add any number of tags inside that grid, because grid can have multiple children.
  1. <Window x:Class="A.MainWindow"    
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
  6.         xmlns:local="clr-namespace:A"    
  7.         mc:Ignorable="d"    
  8.         Title="MainWindow" Height="150" Width="300">    
  9.     <Grid x:Name="MainGrid">    
  10.         <Button x:Name="SubmitButton"    
  11.                Foreground="White"    
  12.                Height="20"    
  13.                Width="100">    
  14.             <Button.Template>    
  15.                 <ControlTemplate x:Name="ButtonElipse">    
  16.                     <Grid>    
  17.                         <Ellipse Fill="Gray"/>    
  18.                         <ContentPresenter     
  19.                             Content="Submit"     
  20.                             VerticalAlignment="Center"    
  21.                             HorizontalAlignment="Center"/>    
  22.                     </Grid>    
  23.                 </ControlTemplate>    
  24.             </Button.Template>    
  25.         </Button>    
  26.     </Grid>    
  27. </Window>     
Content Template And Data Template In WPF

Content Template And Data Template In WPF
 
Content Template And Data Template In WPF

As you can see, new ControlTemplate has been assigned to a Button.

Now let's load our ControlTemplate in ResourceDictionary and fetch it from there.

ResourceDictionaryTemplate.xaml 
  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  2.                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  3.                     xmlns:local="clr-namespace:A">    
  4.         <Thickness x:Key="MarginTR">0 5 5 0</Thickness>    
  5.     <ControlTemplate x:Key="EllipseButton">    
  6.         <Grid>    
  7.             <Ellipse Fill="Gray"/>    
  8.             <ContentPresenter     
  9.                             Content="Submit"     
  10.                             VerticalAlignment="Center"    
  11.                             HorizontalAlignment="Center"/>    
  12.         </Grid>    
  13.     </ControlTemplate>    
  14. </ResourceDictionary>     
MainWindow.xaml
 
First, you need to add Window.Resources.

Second use Tag Template to bind the EllipseButton ControlTemplate.
  1. <Window x:Class="A.MainWindow"    
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
  6.         xmlns:local="clr-namespace:A"    
  7.         mc:Ignorable="d"    
  8.         Title="MainWindow" Height="150" Width="300">    
  9.     <Window.Resources>    
  10.         <ResourceDictionary Source="ResourceDictionaryTemplate.xaml"/>    
  11.     </Window.Resources>    
  12.     <Grid x:Name="MainGrid">    
  13.         <Button x:Name="SubmitButton"    
  14.                Foreground="White"    
  15.                Template="{StaticResource EllipseButton}"    
  16.                Height="20"    
  17.                Width="100"/>    
  18.     </Grid>    
  19. </Window>    

ContentPresenter


Let's display employee information in UI.

For this we are going to need employee class: Employee.cs
  1. public class Employee  
  2.    {  
  3.        public int EmpId { getset; }  
  4.        public string EmpName { getset; }  
  5.        public string Designation { getset; }  
  6.    } 
MainWindowViewModel: As I am using MVVM, I am updating ViewModel.

But you can do the same in the code behind.
  1. using A.Entities;  
  2. using Prism.Mvvm;  
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.Linq;  
  6. using System.Text;  
  7. using System.Threading.Tasks;  
  8.   
  9. namespace A  
  10. {  
  11.     class MainWindowViewModel : BindableBase  
  12.     {  
  13.         #region Properties  
  14.         private Employee _empDetails;  
  15.   
  16.         public Employee EmpDetails  
  17.         {  
  18.             get { return _empDetails; }  
  19.             set { _empDetails = value; }  
  20.         }  
  21.  
  22.         #endregion  
  23.  
  24.         #region Constructor  
  25.         public MainWindowViewModel()  
  26.         {  
  27.             EmpDetails = new Employee()  
  28.             {  
  29.                 EmpId = 1,  
  30.                 EmpName = "Rikam",  
  31.                 Designation = "Software Eng."  
  32.             };  
  33.         }  
  34.         #endregion  
  35.     }  

Finally, MainWindow.xaml:
  1. <Window x:Class="A.MainWindow"    
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
  6.         xmlns:local="clr-namespace:A"    
  7.         mc:Ignorable="d"    
  8.         Title="MainWindow" Height="150" Width="300">    
  9.     <Window.Resources>    
  10.         <ResourceDictionary>    
  11.             <ResourceDictionary.MergedDictionaries>    
  12.                 <ResourceDictionary Source="ResourceDictionaryTemplate.xaml"/>    
  13.             </ResourceDictionary.MergedDictionaries>    
  14.         </ResourceDictionary>    
  15.     </Window.Resources>    
  16.     <Grid x:Name="MainGrid">    
  17.         <ContentPresenter x:Name="EmployeeDetails" Content="{Binding EmpDetails}">    
  18.             <ContentPresenter.ContentTemplate>    
  19.                 <DataTemplate>    
  20.                     <Grid>    
  21.                         <Grid.RowDefinitions>    
  22.                             <RowDefinition Height="Auto"/>    
  23.                             <RowDefinition Height="Auto"/>    
  24.                             <RowDefinition Height="Auto"/>    
  25.                         </Grid.RowDefinitions>    
  26.                         <Grid.ColumnDefinitions>    
  27.                             <ColumnDefinition/>    
  28.                             <ColumnDefinition/>                                
  29.                         </Grid.ColumnDefinitions>    
  30.                         <Label Content="Employee Id:"/>    
  31.                         <Label Content="{Binding EmpId}"     
  32.                                Grid.Column="1"/>    
  33.                         <Label Content="Employee Name:"    
  34.                                Grid.Row="1"/>    
  35.                         <Label Content="{Binding EmpName}"    
  36.                                Grid.Row="1"    
  37.                                Grid.Column="1"/>    
  38.                         <Label Content="Employee Designation:"    
  39.                                Grid.Row="2"/>    
  40.                         <Label Content="{Binding Designation}"    
  41.                                Grid.Column="1"    
  42.                                Grid.Row="2"/>    
  43.                     </Grid>    
  44.                 </DataTemplate>    
  45.             </ContentPresenter.ContentTemplate>    
  46.         </ContentPresenter>    
  47.         <Button x:Name="SubmitButton"    
  48.                Template="{StaticResource EllipseButton}"    
  49.                VerticalAlignment="Bottom"    
  50.                Margin="0 0 0 10"    
  51.                Foreground="White"    
  52.                Height="20"    
  53.                Width="100"/>    
  54.     </Grid>    
  55. </Window>     
Content Template And Data Template In WPF
 
We need to use ContentPresenter when we want to use DataTemplate.

Then you must specify its content,  and the source from where our inner control is supposed to fetch its data.

Then bind each property as you wish. 
 
I hope  this article has helped you to understand Templates in WPF.
 
If you have in further queries, you can connect with me @