
 May 29, 2012 08:43 by 
 Scott 
     
One of the powerful new features around templating in the Silverlight 5 beta is the ability to produce a DataTemplate that will be implicitly associated with a particular data type.
 For example, if I have these 2 simple types Person and Vehicle; 
public class Person   
 {   
   public string FirstName { get; set; }   
   public string LastName { get; set; }   
   public int Age { get; set; }   
 }   
 public class Vehicle   
 {   
   public string Type { get; set; }   
   public int Wheels { get; set; }   
 }   
 then I can define implicit templates for them by writing templates such as these; 
<UserControl.Resources>  
     <DataTemplate  
       DataType="local:Person">  
       <StackPanel>  
         <TextBlock  
           Text="{Binding FirstName}" />  
         <TextBlock  
           Text="{Binding LastName}" />  
         <TextBlock  
           Text="{Binding Age}" />  
       </StackPanel>  
     </DataTemplate>  
     <DataTemplate  
       DataType="local:Vehicle">  
       <StackPanel>  
         <TextBlock  
           Text="{Binding Type}" />  
         <TextBlock  
           Text="{Binding Wheels}" />  
       </StackPanel>  
     </DataTemplate>  
   </UserControl.Resources>   
 where I have not specified a  Key for these resources but have, instead, specified a DataType and that’s enough for Silverlight to figure it out. 
 If I have a scenario like this one where I have a  ListBox bound to a set of Items; 
<Grid>   
   <Grid.RowDefinitions>   
     <RowDefinition />   
     <RowDefinition   
       Height="Auto" />   
     <RowDefinition   
       Height="Auto" />   
   </Grid.RowDefinitions>   
   <ListBox   
     ItemsSource="{Binding Items}">   
   </ListBox>   
   <Button   
     Command="{Binding AddPerson}"  
     Content="Add Person"  
     Grid.Row="1" />   
   <Button   
     Command="{Binding AddVehicle}"  
     Content="Add Vehicle"  
     Grid.Row="2" />   
 </Grid>   
 with a  DataContext providing a view model like this one;
 
 public class ViewModel   
 {   
   public ViewModel()   
   {   
     this.Items = new ObservableCollection<object>();   
     this.AddPerson = new SimpleCommand(() =>   
       {   
         this.Items.Add(   
           new Person()   
           {   
             FirstName = "TestFirst",   
             LastName = "TestLast",   
             Age = 22   
           });   
       });   
     this.AddVehicle = new SimpleCommand(() =>   
       {   
         this.Items.Add(   
           new Vehicle()   
           {   
             Type = "Car",   
             Wheels = 4   
           });   
       });   
   }   
   public ObservableCollection<object> Items { get; set; }   
   public ICommand AddPerson { get; set; }   
   public ICommand AddVehicle { get; set; }   
 }  
 then whenever I add a  Person to the ListBox the runtime will find the right implicit template to display the Person and if I add a Vehicle to the ListBox then the runtime will do the right thing there too;
 
 and, if for example I was to make my ViewModel implement property change notification and then bind up a new property called  SelectedItem to my ListBox then I can bring in a ContentPresenter and it will also make use of the implicit template as in;
<UserControl.Resources>    
   <DataTemplate   
     DataType="local:Person">   
     <StackPanel>   
       <TextBlock   
         Text="{Binding FirstName}" />   
       <TextBlock   
         Text="{Binding LastName}" />   
       <TextBlock   
         Text="{Binding Age}" />   
     </StackPanel>   
   </DataTemplate>   
   <DataTemplate   
     DataType="local:Vehicle">   
     <StackPanel>   
       <TextBlock   
         Text="{Binding Type}" />   
       <TextBlock   
         Text="{Binding Wheels}" />   
     </StackPanel>   
   </DataTemplate>   
</UserControl.Resources>    
<UserControl.DataContext>    
   <local:ViewModel />   
</UserControl.DataContext>    
<Grid>    
   <Grid.ColumnDefinitions>   
     <ColumnDefinition />   
     <ColumnDefinition />   
   </Grid.ColumnDefinitions>   
   <Grid.RowDefinitions>   
     <RowDefinition />   
     <RowDefinition   
       Height="Auto" />   
     <RowDefinition   
       Height="Auto" />   
   </Grid.RowDefinitions>   
   <ListBox   
     ItemsSource="{Binding Items}"  
     SelectedValue="{Binding SelectedItem,Mode=TwoWay}" />   
   <Button   
     Command="{Binding AddPerson}"  
     Content="Add Person"  
     Grid.Row="1" />   
   <Button   
     Command="{Binding AddVehicle}"  
     Content="Add Vehicle"  
     Grid.Row="2" />   
   <ContentPresenter   
     Grid.Column="1"  
     Content="{Binding SelectedItem}" />   
</Grid>   
 and so then both the ListBox on the left and the ContentPresenter on the right are using implicit templates to display content; 
 
 (as an aside, I also tried this with a  ContentPresenter inside a Tooltip and it didn’t work for me so far in the beta).
 Naturally, you can override these implicit templates so if I want a different template for my  ContentPresenter I can simply add an implicit template that is nearer to the ContentPresenter in the hierarchy of resource resolution as in; 
<UserControl.Resources>   
   <DataTemplate  
     DataType="local:Person">  
     <StackPanel>  
       <TextBlock  
         Text="{Binding FirstName}" />  
       <TextBlock  
         Text="{Binding LastName}" />  
       <TextBlock  
         Text="{Binding Age}" />  
     </StackPanel>  
   </DataTemplate>  
   <DataTemplate  
     DataType="local:Vehicle">  
     <StackPanel>  
       <TextBlock  
         Text="{Binding Type}" />  
       <TextBlock  
         Text="{Binding Wheels}" />  
     </StackPanel>  
   </DataTemplate>  
</UserControl.Resources>   
<UserControl.DataContext>   
   <local:ViewModel />  
</UserControl.DataContext>   
<Grid>   
   <Grid.ColumnDefinitions>  
     <ColumnDefinition />  
     <ColumnDefinition />  
   </Grid.ColumnDefinitions>  
   <Grid.RowDefinitions>  
     <RowDefinition />  
     <RowDefinition  
       Height="Auto" />  
     <RowDefinition  
       Height="Auto" />  
   </Grid.RowDefinitions>  
   <ListBox  
     ItemsSource="{Binding Items}"  
     SelectedValue="{Binding SelectedItem,Mode=TwoWay}" />  
   <Button  
     Command="{Binding AddPerson}"  
     Content="Add Person"  
     Grid.Row="1" />  
   <Button  
     Command="{Binding AddVehicle}"  
     Content="Add Vehicle"  
     Grid.Row="2" />  
   <Grid  
     Grid.Column="1">  
     <Grid.Resources>  
       <DataTemplate  
         DataType="local:Vehicle">  
         <StackPanel  
           Orientation="Horizontal">  
           <TextBlock  
             Text="{Binding Type}" />  
           <TextBlock  
             Text="{Binding Wheels}" />  
         </StackPanel>  
       </DataTemplate>  
     </Grid.Resources>  
     <ContentPresenter  
         Grid.Column="1"  
         Content="{Binding SelectedItem}"/>  
   </Grid>  
</Grid>  
 
 and, naturally, you can also mix/match this implicit approach with the explicit approach that you’d use in Silverlight 4 today.  
 I think this is a pretty powerful addition to the Silverlight 5 binding/templating abilities and it’ll be interesting to see what other folks and frameworks do with it.