Different Types Of Templates In WPF

Introduction

Each control has its own default template associated with it. Using styles, you can only modify the default associated template. WPF enables you to change the look and feel of the controls and this can be achieved by using the templates.

There are four types of templates, which are shown below.

  • Control Template
  • Data Template
  • ItemsPanel Template
  • HierarchalData Template

Control Template

Control Template enables you to customize the default appearance and behavior of the control. This can be achieved by setting the dependency property “Template” to an instance of Control Template.

Example

Let’s create a Control Template for a button.

  1. Create a new Project “Templates” and add XAML file ControlTemplate.xaml

    ControlTemplate

  2. Place a button in it. 
    1. <Grid>  
    2.     <Button Margin="50” Foreground=" Black " Content="Custom " ></Button>  
    3. </Grid  
  3. Add Button.Template tag and create ControlTemplate within it, as shown below.
    1. <Button Margin="50” Foreground=" Black " Content="Custom " >
      1. <Button.Template>  
      2. <ControlTemplate TargetType="{x:Type Button} ">  
      3. <Grid>  
      4. <Ellipse Width="210 " Height="110 " Fill="Black "/>  
      5. <Ellipse Width="200 " Height="100 " Name="Button " Fill="Brown” />  
      6. <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid>  
      7. </ControlTemplate>  
      8. </Button.Template>  
      9. </Button>  

    As soon as you create a ControlTemplate, the button will replace its default template with the template created by you.

    ControlTemplate

    Data Template

    Data Template enables you to customize the appearance of the data objects. It is beneficial when a collection of objects binds with ItemControls like ListView, ListBox,ComboBox.

    To understand the importance of Data Templates, let’s see what happens when a ListBox is created without Data Template.

    Steps - ListBox without DataTemplate

    1. Add the new XAML file DataTemplate.xaml and place a Listbox control in it.
      1. <Grid>  
      2.     <ListBox Name="dataTemplate"></ListBox>  
      3. </Grid>  
    2. Create a class “Book”, as shown below.
      1. public class Book {  
      2.     public string CoverImage {  
      3.         get;  
      4.         set;  
      5.     }  
      6.     public string Name {  
      7.         get;  
      8.         set;  
      9.     }  
      10.     public string Author {  
      11.         get;  
      12.         set;  
      13.     }  
      14. }  
    3. Create a collection of instance of class Book and bind the collection with the ListBox, as shown below.
      1. public partial class DataTemplate: Window {  
      2.     public DataTemplate() {  
      3.         InitializeComponent();  
      4.         // Create the Collection  
      5.         List < Book > bookList = new List < Book > ();  
      6.         bookList.Add(new Book() {  
      7.             CoverImage = @ "images\ComputerNetworking6E.jpg",  
      8.                 Name = "Computer Networking",  
      9.                 Author = "James F. Kurose"  
      10.         });  
      11.         bookList.Add(new Book() {  
      12.             CoverImage = @ "images\software-engineering-oup.jpg",  
      13.                 Name = "Software Engineering",  
      14.                 Author = "Deepak Jain"  
      15.         });  
      16.         bookList.Add(new Book() {  
      17.             CoverImage = @ "images\MyCoverImage.jpg",  
      18.                 Name = "HTML 5",  
      19.                 Author = "Adam McDaniel"  
      20.         });  
      21.         bookList.Add(new Book() {  
      22.             CoverImage = @ "images\9780134133164.jpg",  
      23.                 Name = "Visual Studio 2015",  
      24.                 Author = "Lars Powers"  
      25.         });  
      26.         //Bind it with the ListBox  
      27.         this.dataTemplate.ItemsSource = bookList;  
      28.     }  
      29. }  

    Output

    ControlTemplate

    The default template of the data object is a Textblock. Thus, if we bind the objects to it without the data template, ToString() method is called on it and the data is shown as the string.

    Now, let’s see what happens with the data template.

    Additional Step - ListBox with DataTemplate

    Add ListBox.ItemTemplate tag and create the Data Template within it, as shown below.

    1. <ListBox Name="dataTemplate">  
    2.     <ListBox.ItemTemplate>  
    3.         <DataTemplate>  
    4.             <StackPanel Orientation="Horizontal" VerticalAlignment="Center">  
    5.                 <Image Source="{Binding CoverImage}" Height="200" Width="150"></Image>  
    6.                 <StackPanel Orientation="Vertical" VerticalAlignment="Center">  
    7.                     <TextBlock Text="{Binding Name}" FontSize="16"></TextBlock>  
    8.                     <TextBlock Text="{Binding Author}" FontSize="16"></TextBlock>  
    9.                 </StackPanel>  
    10.             </StackPanel>  
    11.         </DataTemplate>  
    12.     </ListBox.ItemTemplate>  
    13. </ListBox>  
    Output

    ControlTemplate

    For proper pictorial presentation of the data objects, we should create ItemsControl with DataTemplate but what if we need to customize the default layout of items? In this case ItemsPanelTemplate comes into the picture.

    ItemsPanelTemplate

    ItemsPanelTemplate enables you to customize the panel, which defines the layout of items in ItemControls like ListBox and ListView. Every ItemControl has its default panel.

    For example, Default panel for ListBox is VirtualizingStackPanel.

    To understand it in more detail, let's customize the layout of ListBox in the example stated above. Listbox renders all the items vertically aligned one after the other, each item occupying the whole row. This layout can be customized, as shown below.

    Add ListBox.ItemsPanel tag and create ItemsPanelTemplate within it.
    1. <ListBox.ItemsPanel>  
    2.     <ItemsPanelTemplate>  
    3.         <UniformGrid Columns="3" /> </ItemsPanelTemplate>  
    4. </ListBox.ItemsPanel>  
    ControlTemplate

    Output

    ControlTemplate

    It’s clear now that the template of ItemControls like ListBox & ListView can be customized, using DataTemplate and ItemsPanelTemplate. WPF also provides an ItemControl called TreeView, which is hierarchical in nature. DataTemplate and ItemPanelTemplate are of no use in this case.

    HierarchialDataTemplate

    HierarchialDataTemplate enables you to customize the template of Parent TreeViewItems as well as their Child TreeViewItems.

    Let’s take an example to understand it in more detail
    1. Create a Child class and declare a string type property “Title”, as shown below.
      1. public class Child {  
      2.     public Child(string title) {  
      3.         Title = title;  
      4.     }  
      5.     public string Title {  
      6.         get;  
      7.         set;  
      8.     }  
      9. }  
    2. Create a Parent class and declare a string type property “Title” and a List of type Child class “ChildItems”, as shown below.
      1. public class Parent {  
      2.     public Parent(string title) {  
      3.         Title = title;  
      4.         ChildItems = new List < Child > ();  
      5.     }  
      6.     public string Title {  
      7.         get;  
      8.         set;  
      9.     }  
      10.     public List < Child > ChildItems {  
      11.         get;  
      12.         set;  
      13.     }  
      14. }  
    3. Now, create a dummy Hierarchical collection.
      1. var parent1 = new Parent("Parent #1") {  
      2.     ChildItems = {  
      3.         new Child("Child Item #1.1"),  
      4.         new Child("Child Item #1.2"),  
      5.         new Child("Child Item #1.3")  
      6.     }  
      7. };  
      8. var parent2 = new Parent("Parent #2") {  
      9.     ChildItems = {  
      10.         new Child("Child Item #2.1"),  
      11.         new Child("Child Item #2.2"),  
      12.         new Child("Child Item #2.3")  
      13.     }  
      14. };  
      15. this.treeView.Items.Clear();  
      16. List < Parent > parent = new List < Parent > ();  
      17. parent.Add(parent1);  
      18. parent.Add(parent2);  
    4. Add a TreeView and create a HierarchialDataTemplate for it
      1. <Grid>  
      2.     <TreeView Name="treeView">  
      3.         <TreeView.ItemTemplate>  
      4.             <HierarchicalDataTemplate ItemsSource="{Binding ChildItems}">  
      5.                 <StackPanel Orientation="Horizontal">  
      6.                     <Rectangle Height="10" Width="10" Fill="Red"></Rectangle>  
      7.                     <TextBlock Text="{Binding Title}"></TextBlock>  
      8.                 </StackPanel>  
      9.             </HierarchicalDataTemplate>  
      10.         </TreeView.ItemTemplate>  
      11.     </TreeView>  
      12. </Grid>  
    5. Bind the hierarchical collection parent to the TreeView this.treeView.ItemsSource = parent;

      Output

      ControlTemplate

      The template has changed the look and feel of the parent as well as their child items.

    Conclusion

    There is a lot of things we can do using these templates. I have taken very simple examples to make you understand the basics of all four types of templates. I hope this helps. Thank you for reading.

    Next Recommended Readings