Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Josh Smith MVVM Demo app

In MainWindow we have:

 <HeaderedContentControl 
          Content="{Binding Path=Workspaces}"
          ContentTemplate="{StaticResource WorkspacesTemplate}"
          Header="Workspaces"
          Style="{StaticResource MainHCCStyle}"
          />

In the resources:

  <DataTemplate x:Key="WorkspacesTemplate">
    <TabControl 
      IsSynchronizedWithCurrentItem="True" 
      ItemsSource="{Binding}" 
      ItemTemplate="{StaticResource ClosableTabItemTemplate}"
      Margin="4"
      />
  </DataTemplate>

And in the article says:

A typed DataTemplate does not have an x:Key value assigned to it, but it does have its DataType property set to an instance of the Type class. If WPF tries to render one of your ViewModel objects, it will check to see if the resource system has a typed DataTemplate in scope whose DataType is the same as (or a base class of) the type of your ViewModel object. If it finds one, it uses that template to render the ViewModel object referenced by the tab item's Content property.

My question is:

How does the template know that the type is a collection of workspaces (WorkspaceViewModel)?

like image 942
Sturm Avatar asked Jun 07 '13 07:06

Sturm


2 Answers

It doesn't need to, in the code you've posted. In your sample, you have given a strict value to your content template: you've explicitly used {StaticResource WorkspacesTemplate}, and so a resource with the key of "WorkspacesTemplate is looked up.

Because you've explicitly set the template, it doesn't matter what the intended type is: it'll try to display any object in your Content using the template you've set - with varying degrees of success if you use a type that doesn't match!

In the alternate method you mention - with a "typed DataTemplate", you would declare your datatemplate with <DataTemplate DataType="{x:Type l:WorkSpace}" />. Note that there is no x:Key (and also that I've assumed you have a namespace l mapped to your local code). What happens here is that WPF automatically sets the key of your resource to the DataType (important to note: a resource key doesn't have to be a string!).

Then, when you declare your HeaderedContentControl, you can leave out setting the ContentTemplate. At runtime, when the control is rendered, WPF will check the type of the Content object and find that it is WorkSpace, and it'll then look up a resource with x:Key="{x:Type l:WorkSpace}" - which will match your typed template.

This is a useful way of making consistent representations of data throughout your application, since a typed DataTemplate will be used automatically by any content-presenting control throughout your application.

like image 174
Dan Puzey Avatar answered Sep 24 '22 23:09

Dan Puzey


WPF doesn't really care about the concrete type, it's just need to be some IEnumerable of something, WPF uses the type descriptor to know what the ui binding with.

like image 34
Chen Kinnrot Avatar answered Sep 22 '22 23:09

Chen Kinnrot