views:

35

answers:

1

Is it possible to use templates within templates?

For instance, I have the following two templates:

<HierarchicalDataTemplate 
    x:Key="RecursiveTemplate"
    ItemsSource="{Binding Children}">
    <StackPanel Margin="1" Orientation="Horizontal">
        <Ellipse Fill="DarkGreen" Width="14" Height="14"/>
        <TextBlock 
            MouseDown="OnTreeMouseDown" 
            TargetUpdated="OnTargetUpdated"
            Visibility="{Binding Editing, Converter={StaticResource visibilityInverter}}" 
            Margin="5" 
            Text="{Binding Name}"/>
        <TextBox 
            PreviewKeyDown="OnTreeKeyDown" 
            Visibility="{Binding Editing, Converter={StaticResource visibilityConverter}}" 
            Margin="2" 
            Text="{Binding Name}"/>
    </StackPanel>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate 
    x:Key="ContainerTemplate"
    ItemsSource="{Binding Children}">
    <StackPanel Margin="1" Orientation="Horizontal">
        <Ellipse Fill="DarkBlue" Width="14" Height="14"/>
        <TextBlock 
            MouseDown="OnTreeMouseDown" 
            TargetUpdated="OnTargetUpdated"
            Visibility="{Binding Editing, Converter={StaticResource visibilityInverter}}" 
            Margin="5" 
            Text="{Binding Name}"/>
        <TextBox 
            PreviewKeyDown="OnTreeKeyDown" 
            Visibility="{Binding Editing, Converter={StaticResource visibilityConverter}}" 
            Margin="2" 
            Text="{Binding Name}"/>
    </StackPanel>
</HierarchicalDataTemplate>

There's a section of identical XAML:

<TextBlock 
     MouseDown="OnTreeMouseDown" 
     TargetUpdated="OnTargetUpdated"
     Visibility="{Binding Editing, Converter={StaticResource visibilityInverter}}" 
     Margin="5" 
     Text="{Binding Name}"/>
<TextBox 
     PreviewKeyDown="OnTreeKeyDown" 
     Visibility="{Binding Editing, Converter={StaticResource visibilityConverter}}" 
     Margin="2" 
     Text="{Binding Name}"/>

Is it possible to move that to a resource and refer to it by name, rather than repeat it?

+1  A: 

The answer appears to be "almost"

<Style x:Key="textBlockStyle" TargetType="TextBlock">
   <Setter Property="Visibility" Value="{Binding Editing, Converter={StaticResource visibilityInverter}}"/>
   <Setter Property="Margin" Value="4"/>
   <Setter Property="Text" Value="{Binding Name}"/>
   <EventSetter Event="MouseDown" Handler="OnTreeMouseDown"/>
</Style>

<Style x:Key="textBoxStyle" TargetType="TextBox">
   <Setter Property="Visibility" Value="{Binding Editing, Converter={StaticResource visibilityConverter}}"/>
   <Setter Property="Margin" Value="1"/>
   <Setter Property="Text" Value="{Binding Name, NotifyOnSourceUpdated=True}"/>
   <EventSetter Event="PreviewKeyDown" Handler="OnTreeKeyDown"/>
</Style>

Then the templates reduce to

<HierarchicalDataTemplate 
    x:Key="RecursiveTemplate"
    ItemsSource="{Binding Children}">
    <StackPanel Margin="1" Orientation="Horizontal">
        <Ellipse Fill="DarkGreen" Width="14" Height="14"/>
        <TextBlock 
            Style="{StaticResource textBlockStyle}"/>
        <TextBox 
            SourceUpdated="OnSourceUpdated"
            Style="{StaticResource textBoxStyle}"/>
    </StackPanel>
</HierarchicalDataTemplate>

However, note you cannot put SourceUpdated in a style, as it's not covered by EventSetter

imekon