Search code examples
wpfxamldatatemplate

How to specifiy content template based on type


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>

Solution

  • 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>