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

Implicit DataTemplate in Silverlight 4 Composite UI – Get Ready for Silverlight 5–Part I

0.00/5 (No votes)
19 May 2011 2  
Implicit DataTemplate in Silverlight 4 Composite UI – Get ready for Silverlight 5–Part I

I'm using Prism 4 in one of my Silverlight 4 Composite UI. Working with Prism, there are two ways populating a Region: You can populate it with a UI element, which is the view, or placing the view-model directly. Personally, I support the idea that a UI element must not be treated directly from the Application logic, and there should be ZERO UI elements in the Application logic. So natively, populating a region with a view-model instead of a view sounds more reasonable for me.

With WPF, things are easier. All you have to do is to create an Implicit Data Template for the view-model and let WPF do the rest.

If you're a Silverlight developer and you never developed WPF before, implicit Data Template may sound unfamiliar.

An implicit data template is a regular Data Template which targets a specific type, in our case a specific view-model. Once placing an instance of that type inside the content of a ContentControl or as item in ItemsControl, that implicit Data Template is automatically picked by the framework and is used to create a visual element, added to the visual tree of the relevant item.

In Silverlight 4, there is no implicit Data Template (there will be in Silverlight 5 which is Beta at the time of this writing). In that case, you should specify the Data Template directly on the control itself which is a big disadvantage in many cases including adding the view-model directly to the Region.

Searching over the internet, I found one solution for implementing implicit Data Template in Silverlight 4. Personally, I didn't like it for two reasons:

  1. All Data Templates must be placed inside the Application resources only, and there is no option to override them in lower levels of the Visual Tree.
  2. There is no simple way specifying the implicit Data Template, and migrating to Silverlight 5 which supports implicit Data Template won't be native.

A bit late but nevertheless, I've developed a solution of my own using an Attached behavior and I want to share it with you.

So here is the usage for both ContentControl (or derived types) and ItemsControl (or derived types):

1.<ContentControl Grid.Column="1"

2.                VerticalAlignment="Center" HorizontalAlignment="Center"

3.                Content="{Binding SelectedShape, Mode=OneWay}" >
4.    <i:Interaction.Behaviors>
5.        <ts:ImplicitContentTemplateBehavior />
6.    </i:Interaction.Behaviors>
7.</ContentControl>
1.<ListBox Grid.Column="0"

2.            VerticalAlignment="Center" HorizontalAlignment="Center"

3.            ItemsSource="{Binding Shapes}"

4.            SelectedItem="{Binding SelectedShape, Mode=TwoWay}">
5.    <i:Interaction.Behaviors>
6.        <ts:ImplicitItemTemplateBehavior/>
7.    </i:Interaction.Behaviors>
8.</ListBox>

In the code snippets above, we have a ContentControl which is bound with a SelectedShape property of type Shape (base class), which may be one of the shapes (derived types): Circle, Rectangle and Triangle, and a ListBox which is bound with a collection of shapes.

Looking at the ListBox, you may see that a different DataTemplate was picked implicitly. Clicking on a shape, you can see it again but now as the content of the ContentControl.

imageimageimage

This behavior is done by the ImplicitContentTemplateBehavior and ImplicitItemTemplateBehavior accordingly.

Here is the DataTemplate for the Rectangle type:

1.<UserControl.Resources>
2.    <DataTemplate x:Key="ImplicitDataTemplate.Rectangle">
3.        <Grid Height="120" Width="120">
4.            <Rectangle StrokeThickness="4">
5.                <Rectangle.Stroke>
6.                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
7.                        <GradientStop Color="White" Offset="0"/>
8.                        <GradientStop Color="#FFC24400" Offset="0.992"/>
9.                    </LinearGradientBrush>
10.                </Rectangle.Stroke>
11.                <Rectangle.Fill>
12.                    <LinearGradientBrush EndPoint="0.5,1" 

                           MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
13.                        <GradientStop Color="#FFFFEACA"/>
14.                        <GradientStop Color="#FFFF6200" Offset="0.989"/>
15.                    </LinearGradientBrush>
16.                </Rectangle.Fill>
17.            </Rectangle>
18.            <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" 

                   VerticalAlignment="Center" />
19.        </Grid>
20.    </DataTemplate>
21.</UserControl.Resources>

As you can see, I placed the data template for the Rectangle in the resources of the view itself (there are additional two, one located at the App resources, and another inside the view's Grid).

Each DataTemplate specifies a unique key which is the Full type name it represents (in the sample above: ImplicitDataTemplate.Rectangle).

Feel free to download the code of this sample from here.

In the next post, I'll provide the behaviors' source code and I'll explain how I implemented each of the behaviors.

Stay tuned!

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