ContentPresenter with ContentTemplateSelector inside an ItemTempate of an ItemsControl

485 Views Asked by At

So, I have an ItemsControl with an ItemTemplate to visualize the items in it's ItemsSource. This Template is a DataTemplate with some controls in it.

  <ItemsControl ItemsSource="{Binding Items}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <TextBlock/>
          <TextBlock/>
          <!-- Content depending on item type -->
          <ContentPresenter Content="{Binding}" ContentTemplateSelector="{StaticResource TemplateSelector}"/>
         <TextBlock/>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
   </ItemsControl>

The items in the ItemsSource can be of different types. Most of the properties of the different types are the same but some properties are different. So I want to put the common content directly inside the DataTemplate but for the content that differs I want to have some kind of placeholder that displays only type-specific content.

So I tried a ContentPresenter with a ContentTemplateSelector. But this does not work. When I set the Content, the TemplateSelector is never called and the name of the underlying viewmodel is displayed. When I do not set the Content, the TemplateSelector is called, but the item in the SelectTemplate function is null.

I do not want to make the whole DataTemplate for each DataType because most of the content is the same and I would have much duplicate code.

1

There are 1 best solutions below

0
Clemens On BEST ANSWER

You do not need a DataTemplateSelector.

Just set the DataType of different DataTemplates in the ItemsControl's Resources. The DataTemplates would automatically be selected according to the type of the item.

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type local:Item1}">
            <TextBlock Text="{Binding Item1Property}"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Item2}">
            <TextBlock Text="{Binding Item2Property}"/>
        </DataTemplate>
    </ItemsControl.Resources>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock ... />
                <ContentPresenter Content="{Binding}"/>
                <TextBlock ... />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>