Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight 5 Beta Rough Notes–Implicit Data Templates

Blogs

Mike Taulty's Blog

Elsewhere

Archives

Note: these are early notes based on some initial experiments with the Silverlight 5 beta, apply a pinch of salt to what you read.

One of the powerful new features around templating in the Silverlight 5 beta is the ability to produce a DataTemplate that will be implicitly associated with a particular data type.

For example, if I have these 2 simple types Person and Vehicle;

  public class Person
  {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
  }
  public class Vehicle
  {
    public string Type { get; set; }
    public int Wheels { get; set; }
  }
then I can define implicit templates for them by writing templates such as these;

<UserControl.Resources>
    <DataTemplate
      DataType="local:Person">
      <StackPanel>
        <TextBlock
          Text="{Binding FirstName}" />
        <TextBlock
          Text="{Binding LastName}" />
        <TextBlock
          Text="{Binding Age}" />
      </StackPanel>
    </DataTemplate>
    <DataTemplate
      DataType="local:Vehicle">
      <StackPanel>
        <TextBlock
          Text="{Binding Type}" />
        <TextBlock
          Text="{Binding Wheels}" />
      </StackPanel>
    </DataTemplate>
  </UserControl.Resources>
where I have not specified a Key for these resources but have, instead, specified a DataType and that’s enough for Silverlight to figure it out.

If I have a scenario like this one where I have a ListBox bound to a set of Items;

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition
        Height="Auto" />
      <RowDefinition
        Height="Auto" />
    </Grid.RowDefinitions>
    <ListBox
      ItemsSource="{Binding Items}">
    </ListBox>
    <Button
      Command="{Binding AddPerson}"
      Content="Add Person"
      Grid.Row="1" />
    <Button
      Command="{Binding AddVehicle}"
      Content="Add Vehicle"
      Grid.Row="2" />
  </Grid>
with a DataContext providing a view model like this one;
  public class ViewModel
  {
    public ViewModel()
    {
      this.Items = new ObservableCollection<object>();
      this.AddPerson = new SimpleCommand(() =>
        {
          this.Items.Add(
            new Person()
            {
              FirstName = "TestFirst",
              LastName = "TestLast",
              Age = 22
            });
        });
      this.AddVehicle = new SimpleCommand(() =>
        {
          this.Items.Add(
            new Vehicle()
            {
              Type = "Car",
              Wheels = 4
            });
        });
    }
    public ObservableCollection<object> Items { get; set; }
    public ICommand AddPerson { get; set; }
    public ICommand AddVehicle { get; set; }
  }
then whenever I add a Person to the ListBox the runtime will find the right implicit template to display the Person and if I add a Vehicle to the ListBox then the runtime will do the right thing there too;

image

and, if for example I was to make my ViewModel implement property change notification and then bind up a new property called SelectedItem to my ListBox then I can bring in a ContentPresenter and it will also make use of the implicit template as in;

  <UserControl.Resources>
    <DataTemplate
      DataType="local:Person">
      <StackPanel>
        <TextBlock
          Text="{Binding FirstName}" />
        <TextBlock
          Text="{Binding LastName}" />
        <TextBlock
          Text="{Binding Age}" />
      </StackPanel>
    </DataTemplate>
    <DataTemplate
      DataType="local:Vehicle">
      <StackPanel>
        <TextBlock
          Text="{Binding Type}" />
        <TextBlock
          Text="{Binding Wheels}" />
      </StackPanel>
    </DataTemplate>
  </UserControl.Resources>
  <UserControl.DataContext>
    <local:ViewModel />
  </UserControl.DataContext>
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition
        Height="Auto" />
      <RowDefinition
        Height="Auto" />
    </Grid.RowDefinitions>
    <ListBox
      ItemsSource="{Binding Items}"
      SelectedValue="{Binding SelectedItem,Mode=TwoWay}" />
    <Button
      Command="{Binding AddPerson}"
      Content="Add Person"
      Grid.Row="1" />
    <Button
      Command="{Binding AddVehicle}"
      Content="Add Vehicle"
      Grid.Row="2" />
    <ContentPresenter
      Grid.Column="1"
      Content="{Binding SelectedItem}" />
  </Grid>
and so then both the ListBox on the left and the ContentPresenter on the right are using implicit templates to display content;

image

(as an aside, I also tried this with a ContentPresenter inside a Tooltip and it didn’t work for me so far in the beta).

Naturally, you can override these implicit templates so if I want a different template for my ContentPresenter I can simply add an implicit template that is nearer to the ContentPresenter in the hierarchy of resource resolution as in;

  <UserControl.Resources>
    <DataTemplate
      DataType="local:Person">
      <StackPanel>
        <TextBlock
          Text="{Binding FirstName}" />
        <TextBlock
          Text="{Binding LastName}" />
        <TextBlock
          Text="{Binding Age}" />
      </StackPanel>
    </DataTemplate>
    <DataTemplate
      DataType="local:Vehicle">
      <StackPanel>
        <TextBlock
          Text="{Binding Type}" />
        <TextBlock
          Text="{Binding Wheels}" />
      </StackPanel>
    </DataTemplate>
  </UserControl.Resources>
  <UserControl.DataContext>
    <local:ViewModel />
  </UserControl.DataContext>
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition
        Height="Auto" />
      <RowDefinition
        Height="Auto" />
    </Grid.RowDefinitions>
    <ListBox
      ItemsSource="{Binding Items}"
      SelectedValue="{Binding SelectedItem,Mode=TwoWay}" />
    <Button
      Command="{Binding AddPerson}"
      Content="Add Person"
      Grid.Row="1" />
    <Button
      Command="{Binding AddVehicle}"
      Content="Add Vehicle"
      Grid.Row="2" />
    <Grid
      Grid.Column="1">
      <Grid.Resources>
        <DataTemplate
          DataType="local:Vehicle">
          <StackPanel
            Orientation="Horizontal">
            <TextBlock
              Text="{Binding Type}" />
            <TextBlock
              Text="{Binding Wheels}" />
          </StackPanel>
        </DataTemplate>
      </Grid.Resources>
      <ContentPresenter
          Grid.Column="1"
          Content="{Binding SelectedItem}"/>
    </Grid>
  </Grid>
and, naturally, you can also mix/match this implicit approach with the explicit approach that you’d use in Silverlight 4 today.

I think this is a pretty powerful addition to the Silverlight 5 binding/templating abilities and it’ll be interesting to see what other folks and frameworks do with it.

As a final note, I’m not sure at the time of writing whether there’s anything in Visual Studio 2010 Sp1 or in the Blend Preview for Silverlight 5 that deals with implicit templates – I’ve not seen anything just yet.


Posted Tue, Apr 26 2011 11:13 AM by mtaulty
Filed under: , ,

Comments

Olusola Adio wrote re: Silverlight 5 Beta Rough Notes–Implicit Data Templates
on Tue, Apr 26 2011 3:55 PM

I just read this article on the use of implicit data templates. This is definitely going to open up more opportunities for Xaml UI design flexibility. Nice and relevant sample. Your rough notes are helping me keep up with the new SL5 goodies coming soon. Please keep it up.

progg.ru wrote Silverlight 5 Beta Rough Notes–Implicit Data Templates
on Sun, May 1 2011 5:51 PM

Thank you for submitting this cool story - Trackback from progg.ru

MSDN UK Team blog wrote Read Mike Taulty’s rough notes on the Silverlight 5 beta
on Fri, May 6 2011 12:19 PM

Wander on over to Mike Taulty’s blog to explore this series of posts detailing Mike’s early rough notes based on initial experiments with the Silverlight 5 beta. Multiple Window Support Markup Extensions Implicit Data Templates Ancestor Relative Binding

Quinton wrote re: Silverlight 5 Beta Rough Notes–Implicit Data Templates
on Tue, May 24 2011 8:26 AM

Hi

How would one change the DataTemplate if you were binding only to a person type, but wanted to differ the template based on a property of person?

For example, if the Person class has a property of Status (Active or Inactive) how would one reflect that in the XAML of the DataTemplate?

Thanks

Q