Tuesday, October 30, 2012

DataTemplateSelector in wpf



Say I have a scenario where I have to apply different templates to different rows of a listbox,datagrid etc  based on some condition .
Example :
I want to show employee data in a listbox . But only if age of employee’s age is greater that 20 he/she will be able to edit their name.
So here for  rows where age> 20 we need a textbox in name column and for others we need textblocks.
For these type of scenarios we need DataTemplateSelector .Below is the way to do it.

Employee class

    public class Employee
    {
        public string name { get; set; }
        public int age { get; set; }
    }

The following steps will give our solution

Step 1:

Create templates in xaml..
 
  <DataTemplate x:Key="t1">  
       <StackPanel Orientation="Horizontal">  
         <TextBlock Text="{Binding Path=age}"/>  
         <TextBlock Text="  "/>  
         <TextBlock Text="{Binding Path=name}"/>  
       </StackPanel>  
     </DataTemplate>  
     <DataTemplate x:Key="t2">  
       <StackPanel Orientation="Horizontal">  
         <TextBlock Text="{Binding Path=age}"/>  
         <TextBlock Text="  "/>  
         <TextBox Text="{Binding Path=name}"/>  
       </StackPanel>  
   </DataTemplate>  



Step 2:
Create a class that inherits DataTemplateSelector class and override its SelectTemplate method.


  public class tselector:DataTemplateSelector  
   {  
     public override DataTemplate SelectTemplate(object item, DependencyObject container)  
     {  
       Employee currEmp = item as Employee;  
       if (currEmp!=null)  
       {  
         if (currEmp.age>20)  
         {  
           return System.Windows.Application.Current.MainWindow.FindResource("t2") as DataTemplate;  
         }  
         else  
         {  
           return System.Windows.Application.Current.MainWindow.FindResource("t1") as DataTemplate;  
         }  
       }  
       return System.Windows.Application.Current.MainWindow.FindResource("t1") as DataTemplate;  
     }  
   }  



Step 3:

In ListBox set ItemtemplateSelector property



    <ListBox  ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource ResourceKey=tsel}" />

The Full xaml is

 <Window x:Class="DataTemplateSelectorSol.MainWindow"  
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
     xmlns:sel="clr-namespace:DataTemplateSelectorSol"  
     Title="MainWindow" Height="350" Width="525">  
   <Window.Resources>  
     <sel:tselector x:Key="tsel"/>  
     <DataTemplate x:Key="t1">  
       <StackPanel Orientation="Horizontal">  
         <TextBlock Text="{Binding Path=age}"/>  
         <TextBlock Text="  "/>  
         <TextBlock Text="{Binding Path=name}"/>  
       </StackPanel>  
     </DataTemplate>  
     <DataTemplate x:Key="t2">  
       <StackPanel Orientation="Horizontal">  
         <TextBlock Text="{Binding Path=age}"/>  
         <TextBlock Text="  "/>  
         <TextBox Text="{Binding Path=name}"/>  
       </StackPanel>  
     </DataTemplate>  
   </Window.Resources>  
   <StackPanel>  
     <ListBox ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource ResourceKey=tsel}" >  
     </ListBox>  
   </StackPanel>  
 </Window>  


 So its simple to implement.

No comments:

Post a Comment