Posted by: Zeeshan Amjad | December 31, 2009

Applying Data Template conditionally


We have studied how can we apply data template. Now we are going to see how can we apply data template conditionally. In other words apply different data template depends on the value of the object.

In our example we are going to make three different data template for bad, average and good student. In this example we just change the message in one text block and its back ground color, but we can define totally different data template. Here is a XAML code to define three data templates.

  1: <DataTemplate x:Key="Bad">
  2: 	<Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
  3: 		<Border.Background>
  4: 			<LinearGradientBrush>
  5: 				<GradientStop Offset="0" Color="LightPink"/>
  6: 				<GradientStop Offset="1" Color="Red"/>
  7: 			</LinearGradientBrush>
  8: 		</Border.Background>
  9: 		<StackPanel Margin="2">
 10: 			<TextBlock Foreground="Black" Text="{Binding ID}"/>
 11: 			<TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 12: 			<TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 13: 			<TextBlock Foreground="Black" Text="Bad Student"/>
 14: 		</StackPanel>
 15: 	</Border>
 16: </DataTemplate>
 17: <DataTemplate x:Key="Average">
 18: 	<Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
 19: 		<Border.Background>
 20: 			<LinearGradientBrush>
 21: 				<GradientStop Offset="0" Color="LightYellow"/>
 22: 				<GradientStop Offset="1" Color="Wheat"/>
 23: 			</LinearGradientBrush>
 24: 		</Border.Background>
 25: 		<StackPanel Margin="2">
 26: 			<TextBlock Foreground="Black" Text="{Binding ID}"/>
 27: 			<TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 28: 			<TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 29: 			<TextBlock Foreground="Black" Text="Average Student"/>
 30: 		</StackPanel>
 31: 	</Border>
 32: </DataTemplate>
 33: <DataTemplate x:Key="Good">
 34: 	<Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
 35: 		<Border.Background>
 36: 			<LinearGradientBrush>
 37: 				<GradientStop Offset="0" Color="LightGreen"/>
 38: 				<GradientStop Offset="1" Color="Green"/>
 39: 			</LinearGradientBrush>
 40: 		</Border.Background>
 41: 		<StackPanel Margin="2">
 42: 			<TextBlock Foreground="Black" Text="{Binding ID}"/>
 43: 			<TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 44: 			<TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 45: 			<TextBlock Foreground="Black" Text="Good Student"/>
 46: 		</StackPanel>
 47: 	</Border>
 48: </DataTemplate>
 49: 

Now we are going to inherit class from Data Template Selector. This class is inherited by object class directly. Here is a class hierarchy of Data Template Selector class.

DataTemplateSelector_01

This class define only one method name select template which returns data template. Here is a class diagram of Data Template Selector.

DataTemplateSelector_02

Here is a class inherited by Data Template Selector.

  1: public class MyTemplateSelector : DataTemplateSelector
  2: {
  3:     public DataTemplate BadStudentTemplate 
  4:     { get; set; }
  5: 
  6:     public DataTemplate AvgStudentTemplate
  7:     { get; set; }
  8: 
  9:     public DataTemplate GoodStudentTemplate
 10:     { get; set; }
 11: 
 12:     public override DataTemplate SelectTemplate(object item, DependencyObject container)
 13:     {
 14:         Student student = item as Student;
 15: 
 16:         if (student != null)
 17:         {
 18:             if (student.Percentage < 50)
 19:                 return BadStudentTemplate;
 20:             else if (student.Percentage >= 50 && student.Percentage < 80)
 21:                 return AvgStudentTemplate;
 22:             else if (student.Percentage > 80)
 23:                 return GoodStudentTemplate;
 24:         }
 25: 
 26:         return BadStudentTemplate;
 27:     }
 28: }
 29: 

Now we are going to make object of this class in XAML. Here is a code to create object of this class in XAML.

  1: <local:MyTemplateSelector x:Key="myTemplateSelectorObj" 
  2: 	BadStudentTemplate="{StaticResource Bad}"
  3: 	AvgStudentTemplate="{StaticResource Average}"
  4: 	GoodStudentTemplate="{StaticResource Good}"/>                                  
  5: 

Data Template Selector is a property of ListBox class. In fact this property is inherted by ItemsControl class. Now we are using our new class object. Here is XAML code to use our new class object.

  1: <ListBox Name="list" Margin="5" HorizontalContentAlignment="Stretch"
  2: 		 ItemTemplateSelector="{StaticResource myTemplateSelectorObj}">
  3: </ListBox>
  4: 

Now if we are storing students information in the list box then it will select different data template depends on the percentage of the student. Here is a complete XAML code of the project.

  1: <Window x:Class="WpfConditionalTemplate.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     xmlns:local="clr-namespace:WpfConditionalTemplate"
  5:     Title="Conditional Template" Height="400" Width="400">
  6:     <Window.Resources>
  7:         <DataTemplate x:Key="Bad">
  8:             <Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
  9:                 <Border.Background>
 10:                     <LinearGradientBrush>
 11:                         <GradientStop Offset="0" Color="LightPink"/>
 12:                         <GradientStop Offset="1" Color="Red"/>
 13:                     </LinearGradientBrush>
 14:                 </Border.Background>
 15:                 <StackPanel Margin="2">
 16:                     <TextBlock Foreground="Black" Text="{Binding ID}"/>
 17:                     <TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 18:                     <TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 19:                     <TextBlock Foreground="Black" Text="Bad Student"/>
 20:                 </StackPanel>
 21:             </Border>
 22:         </DataTemplate>
 23:         <DataTemplate x:Key="Average">
 24:             <Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
 25:                 <Border.Background>
 26:                     <LinearGradientBrush>
 27:                         <GradientStop Offset="0" Color="LightYellow"/>
 28:                         <GradientStop Offset="1" Color="Wheat"/>
 29:                     </LinearGradientBrush>
 30:                 </Border.Background>
 31:                 <StackPanel Margin="2">
 32:                     <TextBlock Foreground="Black" Text="{Binding ID}"/>
 33:                     <TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 34:                     <TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 35:                     <TextBlock Foreground="Black" Text="Average Student"/>
 36:                 </StackPanel>
 37:             </Border>
 38:         </DataTemplate>
 39:         <DataTemplate x:Key="Good">
 40:             <Border Margin="2" BorderBrush="Brown" BorderThickness="1" CornerRadius="5">
 41:                 <Border.Background>
 42:                     <LinearGradientBrush>
 43:                         <GradientStop Offset="0" Color="LightGreen"/>
 44:                         <GradientStop Offset="1" Color="Green"/>
 45:                     </LinearGradientBrush>
 46:                 </Border.Background>
 47:                 <StackPanel Margin="2">
 48:                     <TextBlock Foreground="Black" Text="{Binding ID}"/>
 49:                     <TextBlock Foreground="Black" FontSize="16" Text="{Binding Name}"/>
 50:                     <TextBlock Foreground="Black" Text="{Binding Percentage}"/>
 51:                     <TextBlock Foreground="Black" Text="Good Student"/>
 52:                 </StackPanel>
 53:             </Border>
 54:         </DataTemplate>
 55:         <local:MyTemplateSelector x:Key="myTemplateSelectorObj" 
 56:                                   BadStudentTemplate="{StaticResource Bad}"
 57:                                   AvgStudentTemplate="{StaticResource Average}"
 58:                                   GoodStudentTemplate="{StaticResource Good}"/>                                  
 59:     </Window.Resources>
 60:     <Grid>
 61:         <ListBox Name="list" Margin="5" HorizontalContentAlignment="Stretch"
 62:                  ItemTemplateSelector="{StaticResource myTemplateSelectorObj}">
 63:         </ListBox>
 64:     </Grid>
 65: </Window>
 66: 

and here is complete C# code of the project.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: 
 15: namespace WpfConditionalTemplate
 16: {
 17:     /// <summary>
 18:     /// Interaction logic for Window1.xaml
 19:     /// </summary>
 20:     public partial class Window1 : Window
 21:     {
 22:         public Window1()
 23:         {
 24:             InitializeComponent();
 25: 
 26:             List<Student> students = new List<Student>();
 27: 
 28:             students.Add(new Student(10, "Smith", 82.7));            
 29:             students.Add(new Student(14, "Jon", 62.3));
 30:             students.Add(new Student(17, "Bob", 46.6));
 31:             students.Add(new Student(26, "Alex", 75.1));
 32: 
 33:             list.ItemsSource = students;
 34:         }
 35:     }
 36: 
 37:     public class MyTemplateSelector : DataTemplateSelector
 38:     {
 39:         public DataTemplate BadStudentTemplate 
 40:         { get; set; }
 41: 
 42:         public DataTemplate AvgStudentTemplate
 43:         { get; set; }
 44: 
 45:         public DataTemplate GoodStudentTemplate
 46:         { get; set; }
 47: 
 48:         public override DataTemplate SelectTemplate(object item, DependencyObject container)
 49:         {
 50:             Student student = item as Student;
 51: 
 52:             if (student != null)
 53:             {
 54:                 if (student.Percentage < 50)
 55:                     return BadStudentTemplate;
 56:                 else if (student.Percentage >= 50 && student.Percentage < 80)
 57:                     return AvgStudentTemplate;
 58:                 else if (student.Percentage > 80)
 59:                     return GoodStudentTemplate;
 60:             }
 61: 
 62:             return BadStudentTemplate;
 63:         }
 64:     }
 65: 
 66:     public class Student
 67:     {
 68:         public Student()
 69:         {
 70:         }
 71: 
 72:         public Student(int id, String name, double percentage)
 73:         {
 74:             ID = id;
 75:             Name = name;
 76:             Percentage = percentage;
 77:         }
 78: 
 79:         public int ID
 80:         { get; set; }
 81: 
 82:         public String Name
 83:         { get; set; }
 84: 
 85:         public Double Percentage
 86:         { get; set; }
 87:     }
 88: }
 89: 

Here is the output of this program.

ConditionalTemplateOutput

Advertisements

Responses

  1. […] Control Template Conditionally We have already seen an example of apply data template conditionally and apply style conditionally. Now we are going to extent our concept and apply control template […]

  2. Thanks for this Article. It is very clear, complete and is nicely written. Was very useful. Thanks again. 🙂

    • Thanks to like it. I am glad that it is helpful.

  3. […] in hierarchical grid. We already saw an example of applying data template conditionally here. I picked the idea of creating hierarchical grid from David Sackstein’s blog and here is an […]


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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Categories

%d bloggers like this: