Metro, Windows 8, WinRT

datatemplateselector winrt

by Peter Daukintis

Having used DataTemplateSelectors previously with WPF and similar on Silverlight/Windows Phone I decided to check out whether they work the same in a xaml Metro application. It turns out to be pretty much the same (barring a few things being a bit buggy in the Win8 Developer Preview). Anyway, for reference, here’s a description:

First I created a custom data template selector. This enables you to intercept the decision of which template to use.

Custom Template Selector
  1.     public class MyDataTemplateSelector : DataTemplateSelector
  2.     {
  3.         public DataTemplate PlaceTemplate { get; set; }
  4.         public DataTemplate PersonTemplate { get; set; }
  5.         protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
  6.         {
  7.             if (item is Person)
  8.                 return PersonTemplate;
  9.             if (item is Place)
  10.                 return PlaceTemplate;
  11.  
  12.             return base.SelectTemplateCore(item, container);
  13.         }
  14.     }


I then created an instance in my Main Page’s xaml…

Create Instance
  1. <UserControl.Resources>
  2.     <FlipView:MyDataTemplateSelector x:Key="mySelector" />
  3. </UserControl.Resources>

If you’re used to other xaml technologies you need to be careful with your namespace declaration as the syntax has changed for WinRT:

Using declaration
  1. xmlns:FlipView="using:FlipView"

One thing we haven’t done is to create and set up the DataTemplates:

DataTemplates
  1. <UserControl.Resources>
  2.     <DataTemplate x:Key="myPersonTemplate">
  3.         <Border Background="CornflowerBlue">
  4.             <TextBlock Text="{Binding Name}"
  5.                        FontSize="64"
  6.                        Foreground="Red"
  7.                        HorizontalAlignment="Center"
  8.                        VerticalAlignment="Center" />
  9.         </Border>
  10.     </DataTemplate>
  11.     <DataTemplate x:Key="myPlaceTemplate">
  12.         <Border Background="Orange">
  13.             <Grid>
  14.                 <Image Source="{Binding Image}"></Image>
  15.                 <TextBlock Text="{Binding PlaceName}"
  16.                            FontSize="128"
  17.                            Foreground="AliceBlue"
  18.                            HorizontalAlignment="Center"
  19.                            VerticalAlignment="Center" />
  20.             </Grid>
  21.         </Border>
  22.     </DataTemplate>
  23.     <FlipView:MyDataTemplateSelector x:Key="mySelector"
  24.                                      PersonTemplate="{StaticResource myPersonTemplate}"
  25.                                      PlaceTemplate="{StaticResource myPlaceTemplate}">
  26.     </FlipView:MyDataTemplateSelector>
  27. </UserControl.Resources>

Note that I have created the DataTemplates with a key in the UserControl Resources. This allows me to access the item as a StaticResource; I do this to set the properties on my custom DataTemplateSelector. Now the above may be used with any ItemsControl since that defines an ItemTemplateSelector property on which we can set our custom DataTemplateSelector. It just remains to mock up some data and try it out on a few different Containers:

Dummy Data
  1. private ObservableCollection<object> _collection = new ObservableCollection<object>
  2.     {
  3.         new Person { Name = "fred", Age = 22 },
  4.         new Person { Name = "bob", Age = 22 },
  5.         new Person { Name = "doris", Age = 22 },
  6.         new Place { PlaceName="Moscow", Image="./Images/350px-St__Basil2.jpg"},
  7.         new Person { Name = "mabel", Age = 22 },
  8.     };

Note that I have used the instance type to be the criteria under which I swap the template but of course, the criteria could be anything here. To test on a FlipView just add

FlipView
  1. <FlipView x:Name="myFlip" ItemTemplateSelector="{StaticResource mySelector}" />

 

and set the ItemSource in the code-behind:

ItemSource
  1. myFlip.ItemsSource = _collection;

Just replace the above two steps to try this with a different container.

FlipView seems to suffer from some issues where it rendered unexpected results; sometimes updating the template and sometimes not.

WP_001023 WP_001024

The ListBox gave the expected results:

WP_001027

Tagged , , ,

4 thoughts on “datatemplateselector winrt

  1. Awsome example.
    Can you post a link to a windows 8 VS2012 project.
    I tried following the example but for some reason it’s not working.

Leave a Reply

Your email address will not be published. Required fields are marked *