WPF: Working with Templates

Ravina Deogadkar - Feb 4 '23 - - Dev Community

Each control has its own default template which gives it appearance. Template describes overall visual appearance of control. You can easily create your own templates when you want to customize the visual behavior and visual appearance of a control

Control Template

Control Template enables you to customize the default appearance and behavior of the control. e.g., Button has an appearance and behavior. Click event or mouse hover event are the behaviors which are fired in response to a click and hover.

<UserControl x:Class="WpfDevelopment.ControlTemplateEx"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfDevelopment"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Button MinHeight="100" MinWidth="200" Content="Click Me!">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Ellipse Width="205" Height="105" Fill="Black"></Ellipse>

                        <Ellipse Width="200" Height="100" Fill="LightCoral" Name="Button"></Ellipse>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>

                    <ControlTemplate.Triggers>

                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Button" Property="Fill" Value="Red">
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </Grid>
</UserControl>

Enter fullscreen mode Exit fullscreen mode

Data Template

Data Template defines and specifies the appearance and structure of a collection of data. It enables you to customize the appearance of the data objects. It is mostly used with data related item controls such as ListView, ListItem and ComboBox.

    public class Movie
    {
        public string Title { get; set; }
        public string CoverImage { get; set; }
        public int ReleaseDate { get; set; }
    }
Enter fullscreen mode Exit fullscreen mode

In this example, I have created Movie model class with Title, CoverImage and ReleaseDate fields.

<UserControl x:Class="WpfDevelopment.DataTemplate"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfDevelopment"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <DataTemplate x:Key="MovieTemplate">

                <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Path=CoverImage, FallbackValue=CoverImage}" 
                       Grid.Column="0"
                       Height="200" 
                       Width="150"
                       Margin="5"
                       />

                <StackPanel Orientation="Vertical" Grid.Column="1" VerticalAlignment="Center">
                    <Label Foreground="BlueViolet" 
                           FontWeight="Bold" 
                           FontSize="18" 
                           Content="{Binding Path = Title}"/>
                    <Label Foreground="Crimson" Content="{Binding Path = ReleaseDate}"/>
                </StackPanel>
                </StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView 
                  ItemTemplate="{StaticResource MovieTemplate}"
                  x:Name="MovieListView"/>


    </Grid>
</UserControl>

Enter fullscreen mode Exit fullscreen mode

In this xaml file, DataTemplate is created for ListView control and ItemSource is set from code behind.

    /// <summary>
    /// Interaction logic for DataTemplate.xaml
    /// </summary>
    public partial class DataTemplate : UserControl
    {
        public DataTemplate()
        {
            InitializeComponent();
            List<Movie> movies = new List<Movie>()
            {
                new Movie() { Title = "Logan", CoverImage = @"images/logan.jpg", ReleaseDate = 2006},
                new Movie() { Title = "Top Gun Maverick", CoverImage = @"images/topgun.jpg", ReleaseDate = 2011},
                new Movie(){ Title = "Puss in Boots", CoverImage = @"images/pussinboots.jpg", ReleaseDate = 2022}
            };

            this.MovieListView.ItemsSource = movies;    
        }
    }
Enter fullscreen mode Exit fullscreen mode

In the code behind DataTemplate.xaml.cs file, sample data is created and set as ItemSource for ListView. Images path are set from images\ folder.

Image description

ItemPanelTemplate

ItemPanelTemplate is used to customize the panel that defines the layout of items of ItemControls like ListView, ListBox etc.
Example: Default panel for ListBox is VirtualizingStackPanel.

        <ListView 
                  ItemTemplate="{StaticResource MovieTemplate}"
                  x:Name="MovieListView">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="2" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
Enter fullscreen mode Exit fullscreen mode

ItemPanelTemplate is placed within ListView.ItemsPanel tag.

Image description

HierarchialDataTemplate

HierarchialDataTemplate is used to customize template of parent TreeViewItems as well as of child.

We have created Episode(child) class.

    public class Episode
    {
        public Episode(string title)
        {
            Title = title;
        }
        public string Title { get; set; }
    }
Enter fullscreen mode Exit fullscreen mode

And a Series(Parent class)

    public class Series
    {
        public Series(string title)
        {
            Title = title;
            Episodes = new List<Episode>();
        }

        public string Title { get; set; }

        public List<Episode> Episodes { get; set; }
    }
Enter fullscreen mode Exit fullscreen mode

In this xaml file, HierarchicalDataTemplate is created for TreeView control.

<UserControl x:Class="WpfDevelopment.TreeViewTemplate"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfDevelopment"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TreeView x:Name="treeView">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Episodes}">
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Width="10" Height="10" Fill="BlueViolet" Margin="2"/>
                        <Label Content="{Binding Path=Title}"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</UserControl>

Enter fullscreen mode Exit fullscreen mode

In the code behind, I have created sample data and set as ItemSource for TreeView control.

    public partial class TreeViewTemplate : UserControl
    {
        public TreeViewTemplate()
        {
            InitializeComponent();

            var webSeries = new List<Series>()
            {
                new Series("Friends")
                {
                    Episodes = new List<Episode>()
                    {
                        new Episode("Episode 1"),
                        new Episode("Episode 2"),
                        new Episode("Episode 3"),
                        new Episode("Episode 4")

                    }
                },
                new Series("Young Sheldon")
                {
                    Episodes = new List<Episode>()
                    {
                        new Episode("Episode 1"),
                        new Episode("Episode 2"),
                        new Episode("Episode 3")

                    }
                }
            };
            treeView.Items.Clear();
            treeView.ItemsSource = webSeries;   

        }
    }
Enter fullscreen mode Exit fullscreen mode

Image description

That's it for today, Happy Coding!..

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .