Implicit Data Template in Silverlight 5

[cross posted on the MSDN Canadian developers blog]

One cool new feature of Silverlight 5 is Implicit Data Template. You use Data Templates in Silverlight to control the way you display data while doing DataBinding. Until now DataTemplates were defined inside a control or linked to a resource with a key.

Implicit DataTemplate allows templates to be automatically applied to databound items based on their types (this feature already exists in WPF, so we see more convergence here). This is very useful when you have a list that contains objects of different types, and you want a different layout for each type.

I created a quick sample based on this model:

SocialItem is the base class for multiple *Item derived class.
I can bind a ListBox to a list containing items of type SocialItem, the list can contain any of SocialItem’s derived classes: TwitterItem, FacebookItem, etc…

 

Using Implicit Data Templates allows me to go…

1. From this (Silverlight 4):

2. To this (Silverlight 5):

This is accomplished by (automatically) applying different XAML templates depending on the object’s type.

 

1. Silverlight 4

In the past you would apply a single DataTemplate with a key in Resource to all items in the ListBox:

<UserControl.Resources>
    <DataTemplate x:Key="SocialItemTemplate">
        <StackPanel>
                <TextBlock Text="{Binding UserName}" FontWeight="Bold"/>
            <TextBlock Text="{Binding Status}" TextWrapping="Wrap" HorizontalAlignment="Left"/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Foreground="#FF9F9F9F" TextWrapping="NoWrap"/>
                <TextBlock TextWrapping="Wrap" Text=" / " Foreground="#FF9F9F9F"/>
                <TextBlock Text="{Binding ElapsedTimeSincePost, Mode=OneWay}" Foreground="#FF9F9F9F"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>
<ListBox ItemTemplate="{StaticResource SocialItemTemplate}" ItemsSource="{Binding Items}" />

 

2. Silverlight 5

Now, all DataTemplates are defined in Resource with a DataType attribute set to the target type instead of a key:

<DataTemplate DataType="model:RssfeedItem">
    <Grid VerticalAlignment="Top" Margin="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Image Source="/Images/rssfeed-icon.png" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,5,0"/>
        <StackPanel Grid.Column="1">
            <TextBlock TextWrapping="Wrap" Text="{Binding Title}" FontSize="14" FontFamily="Arial" FontWeight="Bold"/>
            <TextBlock Margin="0" TextWrapping="Wrap" Text="{Binding Text}" FontSize="13.333"/>
            <HyperlinkButton Content="{Binding Url}" Height="21" Margin="0" NavigateUri="{Binding Url}"/>
        </StackPanel>
    </Grid>
</DataTemplate>
 
<DataTemplate DataType="model:TwitterItem">
    <Grid VerticalAlignment="Top" Margin="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Image Source="/Images/twitter-icon.png" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,5,0"/>
        <Border Grid.Column="1">
            <StackPanel>
                <HyperlinkButton Content="{Binding UserName}" HorizontalAlignment="Left" Margin="0" FontWeight="Bold" />
                <TextBlock Text="{Binding Tweet}" VerticalAlignment="Center" FontSize="16" Margin="0" TextWrapping="Wrap"/>
            </StackPanel>
        </Border>
    </Grid>
</DataTemplate>
    
    [...] see full code in download.
<ListBox ItemsSource="{Binding Items}" />

Note the ListBox does not need to reference any template.

Now if you move your DataTemplates to a ResourceDictionary, any time an object appears in a view it will pickup the correct template, that’s cool!

Also note that Implicit Data Templates are polymorphic, so you can define a template for a base class, and redefine if for a derived class.

 

Download my code sample (Silverlight 5 beta)

No Comments