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