0

I know a ControlTemplate is suppose to replace the default one entirely and this seems to work when not using a HierarchicalDataTemplate. However using a HierarchicalDataTemplate my control template seems to be partially used - the TreeViewItem is the control I specified containing an image etc. BUT still appears as a node with the default expander to show its children - not specified in my Template (I want my children to always be shown, but thats beside the point). It looks like this:

      <TreeView>
        <TreeView.Resources>

            <Style x:Key="MyNodeStyle" TargetType="TreeViewItem">
                <Setter Property="SnapsToDevicePixels" Value="true" />
                <Setter Property="OverridesDefaultStyle" Value="true"/>
                <Setter Property="IsExpanded" Value="true"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TreeViewItem">
                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                                <Border CornerRadius="8" BorderThickness="1" Padding="2" Margin="4, 6" BorderBrush="{StaticResource itemBorderBrush}" Background="{StaticResource itemBackgroundBrush}" x:Name="border">
                                    <DockPanel LastChildFill="False">
                                        <StackPanel Orientation="Vertical" DockPanel.Dock="Top" Height="80">
                                            <TextBlock Text="{Binding Path=DisplayValue}" HorizontalAlignment="Center" FontWeight="Bold"/>
                                            <Image Source="MyNode.png" Stretch="None"/>
                                            <TextBlock Text="{Binding Path=Notes}" TextWrapping="Wrap" Width="150"/>                                                   
                                        </StackPanel>
                                    </DockPanel>
                                </Border>
                                <ItemsPresenter />
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" IsItemsHost="True" HorizontalAlignment="Center" />
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <HierarchicalDataTemplate DataType="{x:Type src:MyNode}" ItemsSource="{Binding Path=Children}" >
                <TreeViewItem Style="{StaticResource MyNodeStyle}"/>
            </HierarchicalDataTemplate>

        </TreeView.Resources>

        <!-- Arrange the root items horizontally. -->
        <TreeView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True" Orientation="Horizontal" HorizontalAlignment="Center" />
            </ItemsPanelTemplate>
        </TreeView.ItemsPanel>

    </TreeView>

For some reason only when using a HierarchicalDataTemplate the ItemsPanel and Setter does not seem to be applied and the children are presented in the default expander. How did that expander get there when I am using my own ControlTemplate!?@#$

markmnl
  • 11,116
  • 8
  • 73
  • 109

1 Answers1

1

I don't think you should put the TreeViewItem inside your HierarchicalDataTemplate.

Try this:

<HierarchicalDataTemplate DataType="{x:Type src:MyNode}" ItemsSource="{Binding Path=Children}" >
    <StackPanel Orientation="Vertical" DockPanel.Dock="Top" Height="80">
        <TextBlock Text="{Binding Path=DisplayValue}" HorizontalAlignment="Center" FontWeight="Bold"/>
        <Image Source="MyNode.png" Stretch="None"/>
        <TextBlock Text="{Binding Path=Notes}" TextWrapping="Wrap" Width="150"/>
    </StackPanel>
</HierarchicalDataTemplate>

Now, your template becomes:

<ControlTemplate TargetType="TreeViewItem">
    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
        <Border CornerRadius="8" BorderThickness="1" Padding="2" Margin="4, 6" x:Name="border">
            <DockPanel LastChildFill="False">
                <ContentPresenter ContentSource="Header" />
            </DockPanel>
        </Border>
        <ItemsPresenter />
    </StackPanel>
</ControlTemplate>

Is that how you intended it to look?

Edit: the original expanders are probably there because you only use your style for child items - make your style the ItemContainerStyle for the treeview:

<Window.Resources>
    <Style x:Key="MyNodeStyle" TargetType="TreeViewItem">
        ....

<TreeView ItemContainerStyle="{StaticResource MyNodeStyle}">
Paul Stovell
  • 32,377
  • 16
  • 80
  • 108