Silverlight

DataTemplateSelector in Silverlight

Unlike WPF, Silverlight doesn’t contain a DataTemplateSelector. A DataTemplateSelector is used to select a data template based on the data-bound element and the data object. But, it isn’t hard to build your own.

Start by adding a class to the solution and call it something like “DataTemplateSelector”. Inherit this class  from System.Windows.Controls.ContentControl. The ContentControl class has a property for a data template and a property for content, which you can use to data-bind to. Next, create an override on the OnContentChanged method like this:

protected override void OnContentChanged(object oldContent, object newContent) 
{

}

In the OnContentChanged method, set the template of the  to a template picked from the dictionary. Add something like the code below to method:

if (((int)newContent % 2) == 0)
{
  ContentTemplate = DataTemplateHelper.LoadFromDictionary(
                        "DataTemplateDemo;component/DataTemplates.xaml",
                        "EvenDataTemplate");
}
else
{
  ContentTemplate = DataTemplateHelper.LoadFromDictionary(
                        "DataTemplateDemo;component/DataTemplates.xaml",
                        "OddDataTemplate");
}

Personally, I prefer to place templates in a separate dictionary, just in case I need to share them between xaml files or to keep the other xaml files clean. I use a custom helper class to make this a bit easier. I’ll explain this in a bit.

In your xaml file, use the template selector class as the template of the list:

<ListBox x:Name="ListofNumbers">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <DataTemplateDemo:DataTemplateSelector 
           Content="{Binding}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

 

I use this helper method like below to retrieve templates from dictionaries. To use the code, add a reference too System.Xml.Linq.

public static DataTemplate LoadFromDictionary(string dictionary,
                                              string template)
{
  var doc = XDocument.Load(dictionary);
  var dict = (ResourceDictionary)XamlReader
                    .Load(doc.ToString(SaveOptions.None));
  return dict[template] as DataTemplate;
}

 

A demo project can be downloaded here.

 

Shout it
Tags van Technorati:
dotNed blogger
kick it on DotNetKicks.com

3 comments

  1. Thanks for this simple solution. I’ve used it and like it. One problem I had was that when the source is updated, my selector had to re-evaluate which template to use. So I added some extra code to it, as can be see here. Thanks!

Leave a Reply

Seo wordpress plugin by www.seowizard.org.
%d bloggers like this: