.netwpfdatatemplateitemtemplateselector

DataTemplate Include Another DataTemplate


See below all the DataTemplates have the same first two TextBlock.
In fieldStringTemplate and fieldDateTemplate I would like to refer to fieldTemplate so I am not repeating those two.
How to refer to a DataTemplate from a DataTemplate?

The real application has many more templates and many more common elements.
In the real application these are classes that implement Field.
FieldTemplateSelector is based on the class.

<Window.Resources>
    <local:FieldTemplateSelector x:Key="fieldTemplateSelector"/>
    <DataTemplate x:Key="fieldTemplate">
        <StackPanel>
            <TextBlock Text="{Binding Path=Name}" />
            <TextBlock Text="{Binding Path=DisplayValue}" />
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="fieldStringTemplate">
        <StackPanel>
            <TextBlock Text="{Binding Path=Name}" />
            <TextBlock Text="{Binding Path=DisplayValue}" />
            <TextBox Text="{Binding Path=FieldValue}" />
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="fieldDateTemplate">
        <StackPanel>
            <TextBlock Text="{Binding Path=Name}" />
            <TextBlock Text="{Binding Path=DisplayValue}" />
            <DatePicker SelectedDate="{Binding Path=FieldValue}" />
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Path=Fields}"
             ItemTemplateSelector="{StaticResource fieldTemplateSelector}"
             HorizontalContentAlignment="Stretch">
    </ListBox>
</Grid>

Solution

  • It seems to me it would be much better to do something like this:

    <DataTemplate x:Key="fieldStringTemplate">
       <TextBox Text="{Binding Path=FieldValue}" />
    </DataTemplate>
    
    <DataTemplate x:Key="fieldDateTemplate">
        <DatePicker SelectedDate="{Binding Path=FieldValue}" />
    </DataTemplate>
    
    <!-- and so on... -->
    
    <DataTemplate x:Key="common">
       <StackPanel>
           <TextBlock Text="{Binding Path=Name}" />
           <TextBlock Text="{Binding Path=DisplayValue}" />
           <ContentPresenter Content="{Binding}" 
                             ContentTemplateSelector="{StaticResource fieldTemplateSelector}"/>
       </StackPanel>
    </DataTemplate>
    
    <ListBox ItemsSource="{Binding Path=Fields}"
             ItemTemplate="{StaticResource common}"
             HorizontalContentAlignment="Stretch">
    </ListBox>