Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Silverlight DataTemplateSelector

0.00/5 (No votes)
7 Jul 2010 1  
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:

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:

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:

<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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here