WPF: TabControl & DataTemplates WPF: TabControl & DataTemplates wpf wpf

WPF: TabControl & DataTemplates


First of all, there are two templates involved here:

  • TabControl.ItemTemplate, used to render the TabItem headers
  • TabControl.ContentTemplate, used to render the TabItem contents

If you don't set these properties explicitly then WPF will attempt to resolve them elsewhere. It will walk up the logical tree looking for a resource telling it how to render your view model. If it finds a DataTemplate that has a matching DataType but no key, it will use it to render the view model. If it doesn't find one, it'll default to rendering the ToString value of the object.

So, if you want to be explicit, you want something like this:

<TabControl ItemsSource="{Binding Tabs}">    <TabControl.ItemTemplate>        <DataTemplate>            <TextBlock Text="{Binding TabTitle}"/>        </DataTemplate>    </TabControl.ItemTemplate>    <TabControl.ContentTemplate>        <DataTemplate>            <TextBlock Text="{Binding Text}"/>        </DataTemplate>    </TabControl.ContentTemplate></TabControl>

Since you're not being specific, WPF is attempting to walk up your logical tree to find an appropriate DataTemplate. When it finds it, it uses it to render the view model. Where it doesn't find it, it calls ToString and renders that.

So to address your specific cases:

Just ItemTemplate

You've explicitly stated how to render tab headers but not tab contents. So the former is rendered using the provided DataTemplate, but the latter will default to ToString.

Just DataTemplate

You've not explicitly stated how to render either tab headers or tab contents. Therefore, WPF searches for an appropriate DataTemplate for both. Since both contain an instance of your view model (that's their DataContext) then the same DataTemplate will be used to render tab headers and their contents.

NOTE: you didn't explicitly state that this is what's happening in your question. Correct me if I'm wrong.

Both

In this case, you've explicitly stated how to render tab headers but not tab contents. Therefore, the explicit DataTemplate is used for tab headers and the implicit DataTemplate is used for tab contents.