0

I use a TreeView to create a generic Json Object editor. However, I want to hide the expand/collapse icons completely. I have searched a lot, but couldn't find any working solution so far. Is there a simple way to override the appropriated style to get rid of the collapse/expand functionality?

<TreeView Name="m_TreeView" ItemTemplateSelector="{StaticResource templateSelector}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="True"/>
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

Any ideas how to achive that without creating a complete new TreeViewItem template?

thatguy
  • 21,059
  • 6
  • 30
  • 40
Lori
  • 155
  • 8
  • The icon is a checkbox that is the control to expand / collapse a treeview item. if this is removed, you cannot expand / collapse treeview items. In this case, use a listbox or listview. However, if you want to keep as a treeview, have VS convert the default "ItemContainerStyle" to a local resource and remove the toggle button. – Jeff Dec 17 '20 at 00:12
  • I want the treeview to no be able to collapse/expand at all. Do you have an example for the removing of the toggle button throw ItemContainerStyle change? – Lori Dec 17 '20 at 08:30

1 Answers1

1

The collapse / expand ToggleButton is defined in the control template of the TreeViewItem and there are not any properties to hide them. Consequently, you have to adapt the TreeViewItem template.

You can create a copy of the default TreeViewItem style using Visual Studio or Blend and adapt it. The key is to remove the Expander ToggleButton and its triggers. The column for it must be kept for the indentation. The setter for the IsExpanded property expands all items by default.

<Style TargetType="{x:Type TreeViewItem}">
   <Setter Property="IsExpanded"
           Value="True" />
   <Setter Property="Background"
           Value="Transparent" />
   <Setter Property="HorizontalContentAlignment"
           Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
   <Setter Property="VerticalContentAlignment"
           Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
   <Setter Property="Padding"
           Value="1,0,0,0" />
   <Setter Property="Foreground"
           Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
   <Setter Property="FocusVisualStyle">
      <Setter.Value>
         <Style>
            <Setter Property="Control.Template">
               <Setter.Value>
                  <ControlTemplate>
                     <Rectangle />
                  </ControlTemplate>
               </Setter.Value>
            </Setter>
         </Style>
      </Setter.Value>
   </Setter>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type TreeViewItem}">
            <ControlTemplate.Resources>
               <local:DataTypeConverter x:Key="DataTypeConverter" />
            </ControlTemplate.Resources>
            <Grid>
               <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="19" />
                  <ColumnDefinition Width="Auto"
                                    MinWidth="0" />
                  <ColumnDefinition Width="Auto" />
                  <ColumnDefinition Width="*" />
               </Grid.ColumnDefinitions>
               <Grid.RowDefinitions>
                  <RowDefinition Height="Auto" />
                  <RowDefinition />
               </Grid.RowDefinitions>
               <Border x:Name="Bd"
                       Grid.Column="1"
                       Padding="{TemplateBinding Padding}"
                       Background="{TemplateBinding Background}"
                       BorderBrush="{TemplateBinding BorderBrush}"
                       BorderThickness="{TemplateBinding BorderThickness}"
                       SnapsToDevicePixels="true">
                  <ContentPresenter x:Name="PART_Header"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    ContentSource="Header"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
               </Border>
               <ItemsPresenter x:Name="ItemsHost"
                               Grid.Row="1"
                               Grid.Column="1"
                               Grid.ColumnSpan="2" />
            </Grid>
            <ControlTemplate.Triggers>
               <Trigger Property="IsExpanded"
                        Value="false">
                  <Setter TargetName="ItemsHost"
                          Property="Visibility"
                          Value="Collapsed" />
               </Trigger>
               <Trigger Property="IsSelected"
                        Value="true">
                  <Setter TargetName="Bd"
                          Property="Background"
                          Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                  <Setter Property="Foreground"
                          Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
               </Trigger>
               <MultiTrigger>
                  <MultiTrigger.Conditions>
                     <Condition Property="IsSelected"
                                Value="true" />
                     <Condition Property="IsSelectionActive"
                                Value="false" />
                  </MultiTrigger.Conditions>
                  <Setter TargetName="Bd"
                          Property="Background"
                          Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" />
                  <Setter Property="Foreground"
                          Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}" />
               </MultiTrigger>
               <Trigger Property="IsEnabled"
                        Value="false">
                  <Setter Property="Foreground"
                          Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
   <Style.Triggers>
      <Trigger Property="VirtualizingPanel.IsVirtualizing"
               Value="true">
         <Setter Property="ItemsPanel">
            <Setter.Value>
               <ItemsPanelTemplate>
                  <VirtualizingStackPanel />
               </ItemsPanelTemplate>
            </Setter.Value>
         </Setter>
      </Trigger>
   </Style.Triggers>
</Style>

If you want to remove the indentation of the root level items, you can refer to this related question.

TreeView with first level indentation.

thatguy
  • 21,059
  • 6
  • 30
  • 40
  • Sorry the indentation removing doesn't work, the rest is working. The DataTypeConverter is called, but the value passed in is always null. Any idea what going wrong? – Lori Dec 17 '20 at 10:54
  • @Lori Are there any binding errors in the output? Could you try to replace the trigger with `` just for testing purposes? – thatguy Dec 17 '20 at 11:36
  • I have no binding errors shown in the VS 2019 when starting. If I replace the trigger with what you mentioned, than all identation are gone (as expected). – Lori Dec 17 '20 at 12:45
  • I got it working. I use custom TreeNode types for each item in my Tree. After changing the DataTrigger to `` and the Convert Logic to be aware of resolving the Header of the passed in TreeViewItem and check there if a Parent is present or not. – Lori Dec 17 '20 at 14:11
  • @Lori The sample that I showed only works for statically created `TreeViewItem`s, not for items bound by `ItemsSource` I figured out. However, I have added a link to a related question that focuses on styling top level items. You can either use the approach of splitting the `TreeView` using `ItemsControl` or use the data trigger solutions that you can directly integrate into control template or style. – thatguy Dec 17 '20 at 14:30