In my previous post I talked a little of a new way that WPF allows us to create (and inject) a view by using DataTemplates (or ControlTemplates). I talked about how the use of templates combined with the Presentation Model pattern can help you build fully testable applications.

I was contrasting the benefits of using Presentation Model against the Passive View’s flavor of the MVP pattern when using it in the WPF world. I want to clarify that the Stock Trader reference implementation that’s being shown with the Prism project is not using Passive View (it was in the very first drop, but not anymore)… it has a mix of MVP with Supervising Controller (as of today).

The spike made by the Prism team that I was talking about was released here (get the zip, and the spike is under the PublishedSpikes folder).

The spike was based on the existing UIComposition QuickStart, so not all the code there is related to DataTemplates (as I said, it is just a spike and not production code, but we thought it would be interesting to put it out there). You are very welcomed to check it out. I won’t use the same example as the spike in this post, as I want to focus only on the templating part and leave the rest out.

One very neat thing about using templates, is whenever you add a model into the Visual Tree, WPF will automatically inject the view (template), assign the model as it’s DataContext and render it on screen. How? Well, let’s see an example.

You first need to create the DataTemplate you want to use:

<DataTemplate DataType=”{x:Type models:OrderModel}”>
  <StackPanel>
   
<Grid>
     

      <Label Grid.Row=”0″ Grid.Column=”0″>Customer Name</Label>
     
<TextBox Grid.Row=”0″ Grid.Column=”1″ Text=”{Binding CustomerName}” />
   
</Grid>
   
<TabControl ItemsSource=”{Binding LineModels}” />
    
<Button Command=”{Binding SubmitOrder}”>Submit</Button>
 
</StackPanel>
</DataTemplate>

You could place this portion of XAML in the App.xaml as a resource, but if you do this for every view in one centralized place, that file can get very big, hard to read, hard to manage, and what is worst, all devs or designers will try to edit that file constantly at the same time. Furthermore, if you’re developing different modules (like what you could do with Prism), you will not be able to deploy the modules independently.

Best option: create separate ResourceDictionary files where you can put one or a few tamplates grouped logically. Later on, you can merge these resource dictionaries by using MergedDictionaries in the App.xaml as explained here.

“Ok now, but if I’m using Prism, I cannot accomplish decoupled modules if now my application class has to know about all the resource files in all my modules!”. Fortunately, all that can be done in XAML can be done programatically, so instead of using MergedDictionaries on App.xaml, you could have your Module initialization logic to merge the isolated dictionaries into the application wide ResourceDictionary. In the spike published by the Prism team, this is done with the following code:

ResourceDictionary dictionary = new ResourceDictionary();
dictionary.Source = new Uri(“pack://application:,,,/OrdersModule;Component/OrdersRD.xaml”);
Application.Current.Resources.MergedDictionaries.Add(dictionary);

Now that the initialization has being done, all you need to do is “show” this model. For example:

Window mainWindow = new Window();
mainWindow.Content = new OrderModel();
mainWindow.Show();

On the next posts I’ll try to gather a downloadable sample, and show how to use commands to work in these scenarios. Also I’ll show how to use two-way bindings to communicate actions from the view to the model when commands are not enough.

kick it on DotNetKicks.com

  • Lee Campbell

    Julian I like your ideas around presenting data. Its very “WPF”. :-)

    Any tips coming on best practices for using Commands/Events?

  • http://

    Hi Lee, I’m glad you liked the post.
    Regarding commanding and events, I’m planning to write just about that on my next post for the series, so expect updates on that.

  • Claudio Maccari

    Hi Julian,

    very interesting post cause DataTemplate are a very powerfull feature of WPF but unfortunately there are supported only by Expression Blend Designer, right ?

    Can you please point me to some usefull tips/sample inside Prism about using Commands/Events?

    Thks
    makka

  • Joe

    The problem with programatically modifying resources and merging dictionaries is that the tools fail to pick up the definitions. For example, I have a helper static method that uses reflection to automatically add all ‘converters’ into the application resource dictionary. Blend and VS both don’t run this static method – so this breaks any design experience.

  • http://code.google.com/p/cwpfsamples/ Brett Ryan

    I can get these to appear in expression blend, what I do is just simply open the dictionary in blend and then I can see the resources in the “Resources” tab.

    1). Open ViewModelCompositionSpike in blend
    2). Open ViewModelCompositionSpike.Modules.Employees\Views\EmployeesDetailsViewResourceDictionary.xaml
    3). Go to the “Resources” tab, you will now see the dictionary available, expand it and you will see 3 [DataTemplate]’s.

    Unfortunately these items can’t be named, if you add a key to each (e.g. x:Key=”EmployeeHeader” to the first) it won’t be picked up in the application. If I figure out a way to get blend to recognize a name somehow I’ll let you know :)

    I can’t figure out how the DataTemplate can fire events and handle Commands (especially in ItemsControl’s, if anyone knows how to do that I’d be very interested :)

  • http://panesofglass.org/ Ryan Riley

    This is terrific! I’ve been using CAL on a recent project and switching out what I’ve called View partials inside a UserControl we’ve called a view. The UserControl is essentially a shell containing a menu bar and status bar and an empty code-behind file (except for the InitializeComponent). We’re using separate files for PresentationModels.

    I like the idea of having the PresentationModel inherit from Control and applying a ControlTemplate that could contain the basic buttons and making the existing DataTemplates the views.

    As for binding Commands, you should be able to create a binding at the root panel element like {Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content} and then reference the Command property from the PresentationModel on the button or other control by using Command=”{Binding MyCommand}”.

  • Eric

    Will a downloadable sample of this pattern using Prism still be made available? :)

  • Mike

    Great Post! Thanks for the samples…

    I do have one question however, if I need to have a combobox in my datatemplate, how would I go about setting it’s (the combobox’s) datacontext? I have created a couple of ObjectDataSources and added them to a separate ResourceDictionary and then in the datatemplate I simply bind the datacontext to one of those DataProviders. Will the [mainWindow] from the example above allow me to somehow access that combobox by name or something, in which case I’d have to do the binding via code behind correct? Is there another/better way to do it?

  • jdominguez

    Eric: have been very busy, but I expect to write something in the time soon… I have sample code already drafted.

    Mike: Why do you need to access the combobox? If it’s to get the selected item, you could create a two-way binding that sets a property in the presentation model.

  • KhoonSeang

    Hi Julian,

    Nice article about DataTemplate with PresentationModel!

    May I ask a question: we are trying to adopt the approach of designing DataTemplate, but we face the problem that our Designers cannot “visualize” the end product, as they have to design them piece-by-piece (DataTemplate). How does Expression Blend address this issue?

    Also, do you think it is possible to design before any CLR entities created? They faced the same problem as if no data has been provided, they cannot visualize, for example, how would the list view looks like.

    Thank you in advance for your advice.