WPF: DataTemplate for handling multiple set data


With the help of XAML you can almost change each and every element in your WPF Window UI. Using the templating system you can overload the existing behaviour of control and can apply to other control you were adding . So do onece and reuse later that’s what template and style says.

As name indicate DataTemplate in WPF handles data set. Lets come to our example , I have two type of datas which want to show in customized listbox with images and text.

  • One shows recently added vouchers
  • Another shows list Tasks todo, which is repeating task.
List with Item Template

This can be done with two list boxes as we know, but I can use DataTemplate to design the items and change the look and feel of the items in the list box.

We can create template and styles inside forms XAML inside <Windows.Resources> tag or can place it seperate xaml , so that you can use them throug out your WPF project.

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        Your template Goes Here
    </Window.Resources>
    <Grid>
        
    </Grid>
</Window>

Design the Item Template

Let’s create a item template for showing recent vouchers first, with a grid layout and add Textblock controls and a image controls to show data.

  <DataTemplate x:Key="tr_History">
        <Border x:Name="border" BorderBrush="LightSlateGray" BorderThickness="1" Background="AliceBlue"
          Padding="5" Margin="0">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="20"/>
                    <RowDefinition Height="20"/>
                    <RowDefinition Height="20"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition  Width="40"/>
                    <ColumnDefinition Width="93" />
                     
                </Grid.ColumnDefinitions>
                <Image Source="images/027.png" Grid.Column="0" Grid.Row="0"/>
                <TextBlock FontSize="13" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Foreground="DarkGreen" Text="{Binding eno}" />
                <Image Source="images/calendar.png" Grid.Column="0" Grid.Row="1"/>
                <TextBlock FontSize="13" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Foreground="DarkGreen" Text="{Binding edate, StringFormat=\{0:dd/MM/yyyy\}}"/>
                <Image Source="images\Money-icon.png" Grid.Column="0" Grid.Row="2"/>
                <TextBlock FontSize="13" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" Foreground="DarkGreen" Text="{Binding amount, StringFormat=\{0:0.00\}}"/> 
                 
            </Grid>
        </Border>
    </DataTemplate>

We binded the edate,amount and eno with Textblock control. In xaml attach the itemtemplate as follows

<ListBox  HorizontalContentAlignment="Stretch" ItemTemplate="{StaticResource 
ResourceKey=tr_History}"  Background="White" x:Name="lst_tasks" DataContext="{Binding}" 
ItemsSource="{Binding}"  Margin="0,65,11,0" HorizontalAlignment="Right" Width="176" 
Height="210" VerticalAlignment="Top"/>

And in the code I colleccted the data using Linq as a List and bind its Itemsource as follows

var list = (from r in public_members.receipts.AsEnumerable()
                                        where (r.Field<int>("r_no") != int.Parse(txt_rno.Text.ToString()) && r.Field<decimal>("r_cr_ledger") == crid)
                                        select new { eno = r.Field<int>("r_no"), edate = r.Field<DateTime>("r_date"), amount = r.Field<decimal>("r_cramount") });

                            tr_history_list.ItemsSource = list;

The Task Template

The second template I want to create have similar nature but data will be different one

  <DataTemplate x:Key="Tasks">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="23"/>
                <RowDefinition Height="24"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="40" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Image   Source="images/onebit_20.png"   Grid.Column="0" Grid.Row="0"   />
            <TextBlock   FontSize="13"  Grid.Row="0" Grid.Column="1" Text="{Binding TAGS}" VerticalAlignment="Center"  />
            <Image   Source="images/money.png"    Grid.Column="0" Grid.Row="1" Width="25" Height="25"/>
            <TextBlock FontSize="13"   Grid.Row="1" Grid.Column="1" Text="{Binding TASK_AMOUNT,  StringFormat=\{0:0.00\}}" VerticalAlignment="Center" />

        </Grid>
    </DataTemplate>

Here I binded the TAGS,TASK_ANOUNT to Textblocks. Infact you can design different layour as you like. It need not be the same.

How to change ItemTemplate @ run time

We have learned how to add a item layout in the first template example, now we want to switch between those two layout when it requires. Todo this we need delcare and Template variable and Find our Templates using FindResources command.

 lst_tasks.ItemsSource = list;
DataTemplate pre = this.FindResource("tr_History2") as DataTemplate;
lst_tasks.ItemTemplate = pre;

You can swithch to the second template similar manner.

 lst_tasks.ItemsSource = list;
DataTemplate pre = this.FindResource("Task") as DataTemplate;
lst_tasks.ItemTemplate = pre;

If you have any question please leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.