1

I have a TabControl with a single specific tab, that holds a user control (ui:GeneralControl), and a collection bound to a collection of VMs, using another user control (ui:ModelControl). To do this I use a CompositeCollection and DataTemplates.

I have defined DataTemplates in the control's resources with the target type, but it doesn't get selected as correctly as ContentTemplate.

What's wrong with this code?

<TabControl>
    <TabControl.Resources>
        <CollectionViewSource x:Key="modelsCollection" Source="{Binding OpenedModels}" /> 
        <DataTemplate DataType="{x:Type main:ProjectViewModel}">
              <ui:GeneralControl />
        </DataTemplate>
        <DataTemplate DataType="{x:Type models:ModelViewModel}">
            <ui:ModelControl />
        </DataTemplate>
    </TabControl.Resources>
    <TabControl.ItemsSource>
        <CompositeCollection>
            <TabItem Header="General" />
            <!--Collection of model tabs -->
            <CollectionContainer Collection="{Binding Source={StaticResource modelsCollection}}"/>
        </CompositeCollection>
    </TabControl.ItemsSource>
    <TabControl.ItemTemplate>
        <DataTemplate DataType="models:ModelViewModel">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>
CharlesB
  • 86,532
  • 28
  • 194
  • 218
  • 3
    Automatic template selection based on DataType only works if you do not explicitly specify the tabControl's ItemTemplate. – Clemens Jun 08 '17 at 16:15
  • 1
    You have to use `DataTemplateSelector`. – AnjumSKhan Jun 08 '17 at 16:24
  • @Clemens if I don't specify explicitely ItemTemplate, it works correctly. But then how can I correctly bind tab item's name? – CharlesB Jun 08 '17 at 16:45
  • Don't you see the ModelControl / GeneralControl when you select the tabs or what's your issue? – mm8 Jun 08 '17 at 17:06
  • Have you tried setting the `TabControl`'s [ContentTemplateSelector](https://msdn.microsoft.com/en-us/library/system.windows.controls.tabcontrol.contenttemplateselector(v=vs.110).aspx) to return which template to use for each item? – Andy Jun 08 '17 at 17:07
  • 1
    @AnjumSKhan You don't have to use DataTemplateSelector. – 15ee8f99-57ff-4f92-890c-b56153 Jun 08 '17 at 17:37
  • @Clemens I guess I still have a problem with template selection conflicting with specifying ItemTemplate... I posted another question https://stackoverflow.com/q/44457888/11343 – CharlesB Jun 09 '17 at 12:32
  • @Clemens that's confusing it should be `ContentTemplate` which shouldn't be specified explicitly, however the comment was still helpful for me as I was able to figure it out – Piotr Golacki Aug 03 '22 at 09:35
  • @PiotrGolacki It is also the ItemTemplate of an ItemsControl that should not be set explicitly if you want automatic DataTemplate selection. Be aware that ItemTemplate is the DataTemplate that is used as ContentTemplate by the item container. – Clemens Aug 03 '22 at 09:41
  • @Clemens it works for me with the `ItemTemplate` specified, and if I don't specify it the tabs don't show and I have my templates stacked horizontally instead – Piotr Golacki Aug 03 '22 at 09:43

1 Answers1

2

Thanks to Clemens I figured out I was on the right way, I was just missing binding on one tab:

I have a Data Error, but it's in another question :)

<TabControl>
    <TabControl.Resources>
        <CollectionViewSource x:Key="modelsCollection" Source="{Binding OpenedModels}" /> 
        <DataTemplate DataType="{x:Type main:ProjectViewModel}">
              <ui:GeneralControl />
        </DataTemplate>
        <DataTemplate DataType="{x:Type models:ModelViewModel}">
            <ui:ModelControl />
        </DataTemplate>
    </TabControl.Resources>
    <TabControl.ItemsSource>
        <CompositeCollection>
            <TabItem Header="General" Content="{Binding ProjectViewModel}"/>
            <!--Collection of model tabs -->
            <CollectionContainer Collection="{Binding Source={StaticResource modelsCollection}}"/>
        </CompositeCollection>
    </TabControl.ItemsSource>
    <TabControl.ItemTemplate>
        <DataTemplate DataType="models:ModelViewModel">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>
CharlesB
  • 86,532
  • 28
  • 194
  • 218