Josh Smith MVVM Demo app
Asked Answered
B

2

6

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)?

Bromism answered 7/6, 2013 at 7:57 Comment(0)
M
4

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.

Mischiefmaker answered 7/6, 2013 at 8:13 Comment(0)
M
4

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.

Melodics answered 7/6, 2013 at 8:9 Comment(2)
In some definitions of template I've seen this (in the same project): <ControlTemplate TargetType="{x:Type HeaderedContentControl}"> What is that TargetType?Bromism
When you add target type you don't have to specify the template in the items control, wpf will automatically search for a template with the relvant target type, It's just another option. Best practice is to use both.Melodics
M
4

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.

Mischiefmaker answered 7/6, 2013 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.