Template provide the visual of WPF element, by using WPF we
can change the visual Look and feel of WPF elements
WPF provides three types of Templates to update the Look and
Feel of elements
- Control Template
- Data Template
- ItemPanel Template
Control Template
The Control Template is responsible for visual appearance
and behaviors of wpf UI Controls, by changing the control template we can
change the default look and feel of a controls.
There is a Dependency Property of Template in each control, style or we can
directly define in control template.
Example
Example
Suppose we want to make a round red button
1) In Resource using Control Template with key
We can define ControlTemplete inside resource
<Window.Resources>
<ControlTemplate x:Key="gradientRoundButton">
<Grid>
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Window.Resources>
Full Code
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Window.Resources>
<ControlTemplate x:Key="gradientRoundButton">
<Grid>
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Button Template="{StaticResource gradientRoundButton}" Content="Control
Template"></Button>
</Grid>
</Window>
Now we can see the Content inside the button is missing
For showing the content we need to use ContentPresenter, you
can read about this topic in following post “WPF ContentPresenter”
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Window.Resources>
<ControlTemplate x:Key="gradientRoundButton" TargetType="Button">
<Grid>
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter
HorizontalAlignment="Center" VerticalAlignment="Center"
/>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Button Template="{StaticResource gradientRoundButton}" Content="Control
Template"></Button>
</Grid>
</Window>
2) In Style
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Window.Resources>
<Style x:Key="gradientRoundButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5" />
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource gradientRoundButtonStyle}" Content="Control
Template"></Button>
</Grid>
</Window>
3) Inline Template
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Grid>
<Button Content="Control Template" Foreground="Wheat">
<Button.Template>
<ControlTemplate
TargetType="Button">
<Grid>
<Ellipse Width="120" Height="120" Fill="Gray" />
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Window>
4) Inline Template With Styles
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Grid>
<Button Content="Control Template" Foreground="Wheat">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Width="120" Height="120" Fill="Gray" />
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
5) Using Trigger With Control Template
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Grid>
<Button Content="Control Template" Foreground="Wheat"
>
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Width="120" Height="120" Fill="Gray" Name="grayOuterCircle"
/>
<Ellipse Width="100" Height="100" Name="gradiantInnerCircle">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="grayOuterCircle" Property="Fill" Value="CadetBlue"></Setter>
<Setter TargetName="grayOuterCircle" Property="Cursor" Value="Hand"></Setter>
<Setter TargetName="gradiantInnerCircle" Property="Cursor" Value="Hand"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Window>
6) Some Other Example
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Grid>
<Button Content="Control Template" Foreground="Wheat" Name="btn" >
<Button.Template>
<ControlTemplate
TargetType="Button">
<Grid>
<Ellipse Width="120" Height="120" Fill="Gray" Name="grayOuterCircle"
/>
<Ellipse Width="100" Height="100" Name="gradiantInnerCircle">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<TextBox Width="92" Height="30" Text="{Binding ElementName=btn, Path=Content}"></TextBox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="grayOuterCircle" Property="Fill" Value="CadetBlue"></Setter>
<Setter TargetName="grayOuterCircle" Property="Cursor" Value="Hand"></Setter>
<Setter TargetName="gradiantInnerCircle" Property="Cursor" Value="Hand"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Window>
7) Binding with ViewModel Property
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace MVVMBasics
{
public class Employee
{
public string EmpName { get; set; }
}
/// <summary>
/// Interaction logic for ControlTemplateDemo.xaml
/// </summary>
public partial class ControlTemplateDemo : Window, INotifyPropertyChanged
{
public ControlTemplateDemo()
{
InitializeComponent();
this.DataContext = this;
EmpName = "View Model";
}
private string empName;
public string EmpName
{
get
{
return empName;
}
set
{
empName = value;
OnPropertyChanged("EmpName");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler propChange = PropertyChanged;
if (propChange != null)
{
propChange(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
<Window x:Class="MVVMBasics.ControlTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlTemplateDemo" Height="200" Width="300">
<Grid>
<Button Content="Control Template" Foreground="Wheat" Name="btn" >
<Button.Template>
<ControlTemplate
TargetType="Button">
<Grid>
<Ellipse Width="120" Height="120" Fill="Gray" Name="grayOuterCircle"
/>
<Ellipse Width="100" Height="100" Name="gradiantInnerCircle">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="Green" Offset="0.5"
/>
<GradientStop Color="Red" Offset="1.0"
/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<TextBox Width="92" Height="30" Text="{Binding EmpName}"></TextBox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="grayOuterCircle"
Property="Fill" Value="CadetBlue"></Setter>
<Setter TargetName="grayOuterCircle" Property="Cursor" Value="Hand"></Setter>
<Setter TargetName="gradiantInnerCircle" Property="Cursor" Value="Hand"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Window>
Data Template
Data Template is enable wpf change the appearance how the
data should look for Collection of data, it is mostly used with Item Controls
such as List Box, Combo box, List view, Data Grid
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace MVVMBasics
{
public class Employee
{
public string EmpName { get; set; }
public string Department { get; set; }
}
/// <summary>
/// Interaction logic for DataTemplateDemo.xaml
/// </summary>
public partial class DataTemplateDemo : Window, INotifyPropertyChanged
{
public DataTemplateDemo()
{
InitializeComponent();
EmpList = new ObservableCollection<Employee>();
EmpList.Add(new Employee()
{
EmpName = "Aman",
Department = "HR",
});
EmpList.Add(new Employee()
{
EmpName = "Kishan",
Department = "IT",
});
EmpList.Add(new Employee()
{
EmpName = "Raman",
Department = "IT",
});
EmpList.Add(new Employee()
{
EmpName = "Pinki",
Department = "HR",
});
EmpList.Add(new Employee()
{
EmpName = "Reena",
Department = "Sales",
});
this.DataContext = this;
}
private ObservableCollection<Employee> empList;
public ObservableCollection<Employee> EmpList
{
get
{
return empList;
}
set
{
empList = value;
OnPropertyChanged("EmpList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler propChange = PropertyChanged;
if (propChange != null)
{
propChange(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
<Window x:Class="MVVMBasics.DataTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataTemplateDemo" Height="400" Width="300" Background="Gray">
<Grid>
<ListBox ItemsSource="{Binding EmpList}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Name : " Grid.Column="0" Grid.Row="0"></Label>
<Label Content="Department :
" Grid.Column="0" Grid.Row="1"></Label>
<Label Content="{Binding EmpName}" Grid.Column="1" Grid.Row="0"></Label>
<Label Content="{Binding Department}" Grid.Column="1" Grid.Row="1"></Label>
<Separator Grid.Row="2" Grid.ColumnSpan="2" Background="Black"
/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
In Windows Resource
<Window x:Class="MVVMBasics.DataTemplateDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataTemplateDemo" Height="400" Width="300" Background="Gray">
<Window.Resources>
<DataTemplate x:Key="listBoxDataTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Name : "
Grid.Column="0" Grid.Row="0"></Label>
<Label Content="Department : "
Grid.Column="0" Grid.Row="1"></Label>
<Label Content="{Binding EmpName}" Grid.Column="1" Grid.Row="0"></Label>
<Label Content="{Binding Department}" Grid.Column="1" Grid.Row="1"></Label>
<Separator Grid.Row="2"
Grid.ColumnSpan="2" Background="Black"
/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding EmpList}" ItemTemplate="{StaticResource
listBoxDataTemplate}" >
</ListBox>
</Grid>
</Window>
Inside the ItemTemplate there are "DataTemplate", "HierarchicalDataTemplate"and "ItemContainerTemplate"
Inside the ItemTemplate there are "DataTemplate", "HierarchicalDataTemplate"and "ItemContainerTemplate"