在 ItemsControl 的 ItemTempate 中带有 ContentTemplateSelector 的 ContentPresenter

ContentPresenter with ContentTemplateSelector inside an ItemTempate of an ItemsControl

因此,我有一个带有 ItemTemplate 的 ItemsControl,用于可视化 ItemsSource 中的项目。 此模板是一个包含一些控件的数据模板。

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

ItemsSource 中的项目可以是不同的类型。不同类型的大多数属性是相同的,但有些属性不同。所以我想将通用内容直接放在 DataTemplate 中,但对于不同的内容,我希望有某种仅显示特定类型内容的占位符。

所以我尝试了一个带有 ContentTemplateSelector 的 ContentPresenter。但这不起作用。当我设置内容时,永远不会调用 TemplateSelector 并显示底层视图模型的名称。当我没有设置Content时,调用了TemplateSelector,但是SelectTemplate函数中的item为null。

我不想为每个 DataType 创建整个 DataTemplate,因为大部分内容都是相同的,而且我会有很多重复代码。

您不需要 DataTemplateSelector。

在ItemsControl的Resources中设置不同DataTemplates的DataType即可。 DataTemplates 将根据项目的类型自动选择。

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