Click here to Skip to main content
15,860,943 members
Articles / Programming Languages / C#

Silverlight DataTemplateSelector

Rate me:
Please Sign up or sign in to vote.
4.95/5 (27 votes)
7 Jul 2010CPOL2 min read 114.7K   1.5K   25   30
Implementing DataTemplateSelector on Silverlight

Introduction

One of the cool features of WPF is the ability of apply a Template to a chunk of data according to your own criteria. This is achieved using an implementation of the DataTemplateSelector class. In Silverlight, we are missing this ability of using a DataTemplateSelector and because of this, we have to use more code to fill this hole.

Background

The central idea of this article is to implement a way to use this missing feature by creating a DataTemplateSelector class.

Using the Code

The concept is fairly simple, you have an abstract class, extending from ContentControl that will invoke the virtual method SelectTemplate. The idea is to mimic as much as possible the DataTemplateSelector so that we will have no problem implementing it and reusing it.

The abstract class is simple:

C#
public abstract class DataTemplateSelector : ContentControl
{
    public virtual DataTemplate SelectTemplate(
        object item, DependencyObject container)
    {
        return null;
    }

    protected override void OnContentChanged(
        object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        ContentTemplate = SelectTemplate(newContent, this);
    }
}

Then for our use, as it is in WPF we have to create a class that will have the specific SelectTemplate override that will apply the Template to the specified data chunk. Here is an example:

C#
public class CountryTemplateSelector : DataTemplateSelector
{
    public DataTemplate BrazilTemplate
    {
        get;
        set;
    }

    public DataTemplate UsaTemplate
    {
        get;
        set;
    }

    public DataTemplate EnglandTemplate
    {
        get;
        set;
    }

    public override DataTemplate SelectTemplate(
        object item, DependencyObject container)
    {
        City itemAux = item as City;
        if (itemAux != null)
        {
            if (itemAux.Country == "Brazil")
                return BrazilTemplate;
            if (itemAux.Country == "USA")
                return UsaTemplate;
            if (itemAux.Country == "England")
                return EnglandTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

So if the content of the CountryTemplateSelector is a City, it will return our template based on the country verification, returning the needed template for the class, like in WPF. Of course, since the article only shows the concept I have made a very simple verification, but you can add any logic to your SelectTemplate method.

As I said, fairly simple, like in WPF. But in Silverlight, there will be differences, of course, because the missing ItemTemplateSelector, ContentTemplateSelector,... properties in the controls.

The differences are also minor, instead of using a property that will hold the reference to the StaticResource that represents the DataTemplateSelector in our ResourceDictionary, we will have to add the class as the content of a DataTemplate like this:

XML
<ListBox ItemsSource="{Binding Cities}" HorizontalContentAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:CountryTemplateSelector Content="{Binding}">
                <local:CountryTemplateSelector.BrazilTemplate>
                    <DataTemplate>
                        <Grid Background="Green">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.BrazilTemplate>
                <local:CountryTemplateSelector.UsaTemplate>
                    <DataTemplate>
                        <Grid Background="Blue">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.UsaTemplate>
                <local:CountryTemplateSelector.EnglandTemplate>
                    <DataTemplate>
                        <Grid Background="Red">
                            <TextBlock Text="{Binding Name}"/>
                        </Grid>
                    </DataTemplate>
                </local:CountryTemplateSelector.EnglandTemplate>
            </local:CountryTemplateSelector>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

And there you go. Your control rendering the template needed for the needed scenario.

Thanks

This code is a simple way to apply a very flexible functionality. Hope this aids your development and makes your life a little bit easy. Don't forget to drop a message having your say, really willing to hear more opinions.

Best regards.

History

  • 7th July, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Brazil Brazil
Senior Software Architect from Brazil.

Comments and Discussions

 
GeneralMy vote of 5 Pin
M. Pastore16-Sep-14 2:01
M. Pastore16-Sep-14 2:01 
GeneralSimple solution for static templates only Pin
Todd Beaulieu19-Mar-14 1:46
Todd Beaulieu19-Mar-14 1:46 
QuestionMy Vote Pin
Mycroft Holmes22-Jan-14 22:18
professionalMycroft Holmes22-Jan-14 22:18 
QuestionGood! Thanks! Pin
sangolee19-Jan-14 15:09
sangolee19-Jan-14 15:09 
BugDefault style inheritance Pin
kataik6-Mar-13 10:11
kataik6-Mar-13 10:11 
Question5 Starts post Pin
Member 85990391-Feb-12 7:00
Member 85990391-Feb-12 7:00 
GeneralMy vote of 5 Pin
Markus-81119-Jan-12 18:51
Markus-81119-Jan-12 18:51 
GeneralMy vote of 5 Pin
fabiowitt3-Jun-11 4:28
fabiowitt3-Jun-11 4:28 
GeneralVery Good Raul Pin
fabiowitt3-Jun-11 4:27
fabiowitt3-Jun-11 4:27 
GeneralUpdating templates Pin
MisterTown5-May-11 23:26
MisterTown5-May-11 23:26 
GeneralRe: Updating templates Pin
Michael.Sh879-Jan-12 23:17
Michael.Sh879-Jan-12 23:17 
GeneralHierarchialDataTemplate Pin
Jurie Smit30-Nov-10 11:17
professionalJurie Smit30-Nov-10 11:17 
GeneralRe: HierarchialDataTemplate Pin
da_ponc1-Jan-11 21:06
da_ponc1-Jan-11 21:06 
GeneralRe: HierarchialDataTemplate Pin
Jurie Smit2-Jan-11 20:58
professionalJurie Smit2-Jan-11 20:58 
QuestionError in design view Pin
5774736-Sep-10 7:12
5774736-Sep-10 7:12 
GeneralA reusable datatemplate Pin
Eric Pizon28-Jul-10 9:14
Eric Pizon28-Jul-10 9:14 
GeneralRe: A reusable datatemplate [modified] Pin
Raul Mainardi Neto28-Jul-10 9:25
Raul Mainardi Neto28-Jul-10 9:25 
GeneralRe: A reusable datatemplate Pin
Mthraves28-Dec-10 14:25
Mthraves28-Dec-10 14:25 
GeneralRe: A reusable datatemplate Pin
goliknes22-Jan-11 5:26
goliknes22-Jan-11 5:26 
GeneralRe: A reusable datatemplate Pin
Raul Mainardi Neto24-Jan-11 15:43
Raul Mainardi Neto24-Jan-11 15:43 
GeneralMy vote of 5 Pin
Marcelo Ricardo de Oliveira12-Jul-10 6:52
mvaMarcelo Ricardo de Oliveira12-Jul-10 6:52 
GeneralRe: My vote of 5 Pin
Raul Mainardi Neto12-Jul-10 6:53
Raul Mainardi Neto12-Jul-10 6:53 
GeneralMy vote of 5 Pin
Kunal Chowdhury «IN»9-Jul-10 22:43
professionalKunal Chowdhury «IN»9-Jul-10 22:43 
GeneralRe: My vote of 5 Pin
Raul Mainardi Neto12-Jul-10 1:55
Raul Mainardi Neto12-Jul-10 1:55 
GeneralMy vote of 5 Pin
vikas amin9-Jul-10 10:19
vikas amin9-Jul-10 10:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.