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)?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With