Select entire row of TreeViewItem in WPF

If I set TreeViewItem Background, it only highlights the title. How can I select the whole line?

I found a message, almost solving the problem http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b04f73e2-0b10-4d97-a6da-64df2e30c21d/

But there are some problems: 1. It does not select the entire line 2. The tree has XP style in Vista. I would like it to look the same as in Vista, but if the user changed the theme to XP, it should be XP. 3. So many XAML ...

Any ideas what I should look for?

+58
templates wpf treeviewitem
Mar 20 '09 at 1:08
source share
9 answers

Here we go, a third time charm. If you want something like this.

Full Width TreeView

It takes a little more work. I'm sure there are many ways to do this, but this method uses the length conversion method and the TreeViewItem extension method to get the depth. Both of them are closely related to the TreeViewItem tree, so if you start messing around with templates, you may have problems. Again, here is the important part, and below is the full code.

<ControlTemplate TargetType="{x:Type TreeViewItem}"> <ControlTemplate.Resources> <local:LeftMarginMultiplierConverter Length="19" x:Key="lengthConverter" /> </ControlTemplate.Resources> <StackPanel> <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <Grid Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="19" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <ContentPresenter x:Name="PART_Header" Grid.Column="1" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Grid> </Border> <ItemsPresenter x:Name="ItemsHost" /> </StackPanel> <!-- Triggers --> </ControlTemplate> 

Extension TreeViewDepth

 public static class TreeViewItemExtensions { public static int GetDepth(this TreeViewItem item) { TreeViewItem parent; while ((parent = GetParent(item)) != null) { return GetDepth(parent) + 1; } return 0; } private static TreeViewItem GetParent(TreeViewItem item) { var parent = VisualTreeHelper.GetParent(item); while (!(parent is TreeViewItem || parent is TreeView)) { parent = VisualTreeHelper.GetParent(parent); } return parent as TreeViewItem; } } 

LeftMarginMultiplierConverter

 public class LeftMarginMultiplierConverter : IValueConverter { public double Length { get; set; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var item = value as TreeViewItem; if (item == null) return new Thickness(0); return new Thickness(Length * item.GetDepth(), 0, 0, 0); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new System.NotImplementedException(); } } 

Control

 <TreeView Margin="50" HorizontalContentAlignment="Stretch"> <TreeViewItem Header="test2"/> <TreeViewItem Header="test2"> <TreeViewItem Header="sub test"> <TreeViewItem Header="sub test1-1"/> <TreeViewItem Header="sub test1-2"/> </TreeViewItem> <TreeViewItem Header="sub test2"/> </TreeViewItem> <TreeViewItem Header="test3"/> </TreeView> 

Full TreeViewItem Style

 <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> <!--================================================================= TreeViewItem ==================================================================--> <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton"> <Setter Property="Focusable" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid Width="15" Height="13" Background="Transparent"> <Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="{StaticResource GlyphBrush}" Data="M 4 0 L 8 4 L 4 8 Z"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="TreeViewItemFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Border> <Rectangle Margin="0,0,0,0" StrokeThickness="5" Stroke="Black" StrokeDashArray="1 2" Opacity="0"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="VerticalContentAlignment" Value="{Binding Path=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" Value="{StaticResource TreeViewItemFocusVisual}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <ControlTemplate.Resources> <local:LeftMarginMultiplierConverter Length="19" x:Key="lengthConverter" /> </ControlTemplate.Resources> <StackPanel> <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <Grid Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="19" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <ContentPresenter x:Name="PART_Header" Grid.Column="1" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Grid> </Border> <ItemsPresenter x:Name="ItemsHost" /> </StackPanel> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Width" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Height" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/> </MultiTrigger> <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.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 
+96
Mar 23 '09 at 3:16
source share

Will the TreeViewItem header not stretch?

This problem occurs because the default template for TreeViewItem for WPF is set as 3-column to 2-row Grid . The first line is for the "header" (actually a Border ), and the second line is for ItemsPresenter . These two rows become visible or hidden as needed to expand the tree when you click on the small triangle that occupies the zero column of the Grid .

Both rows really only need one extra column. For example, in the second line, we should not have anything in col-0, row-1, because this pure part should be indented if IsExpanded is true. But the mystery begins when we note that the ItemsPresenter based on col-1, row-1, indicates Grid.ColumnSpan=2 .

Unfortunately, on the top line, the Border that contains the header is set to Grid.Column=1 ... but not ColumnSpan. Since col-2 Grid has Width=* , this means that the header / border will not stretch horizontally.

In other words, it seems to me that a three-column grid design has no purpose other than specifically to prevent the header from stretching. As far as I can tell, a simple 2x2 layout would be more flexible [edit: see Footnote # 2] and would support either stretching or the header is β€œjagged” without stretching through regular WPF alignment mechanisms.

Ideally, we would change the Grid to have only 2 columns instead of 3. Since this is not so simple, instead we will make the header columns of header 2, as ItemsPresenter does.

Well, here is a small, complete, stand-alone (XAML only) working program that demonstrates and fixes the problem:

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:r="clr-namespace:System.Reflection;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib" Width="800" SizeToContent="Manual"> <TreeView ItemsSource="{Binding Source={StaticResource data}}" VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit="Item"> <TreeView.Resources> <ObjectDataProvider x:Key="data" ObjectInstance="{x:Static sys:AppDomain.CurrentDomain}" MethodName="GetAssemblies" /> <HierarchicalDataTemplate DataType="{x:Type r:Assembly}" ItemsSource="{Binding Path=DefinedTypes}" > <TextBlock Text="{Binding Path=Location}" /> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="{x:Type sys:Type}" ItemsSource="{Binding Path=CustomAttributes}"> <TextBlock Text="{Binding Path=Name}" /> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="{x:Type r:CustomAttributeData}" ItemsSource="{Binding Path=ConstructorArguments}"> <TextBlock Text="{Binding Path=AttributeType.Name}" /> </HierarchicalDataTemplate> </TreeView.Resources> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <!-- == == BEGIN HERE == == --> <Style.Resources> <Style TargetType="{x:Type Border}"> <Setter Property="Grid.ColumnSpan" Value="2" /> </Style> </Style.Resources> <!-- == == == END == == == --> <Setter Property="Background" Value="LightBlue" /> </Style> </TreeView.ItemContainerStyle> </TreeView> </Window> 

If you run this program as shown, you will see something like this. This is a fixed behavior that allows you to fully control the behavior of the stretching of the TreeViewItem header:

enter image description here

Note the BEGIN / END part with dashed lines in the XAML source. Basically, I just set Grid.ColumnSpan=2 to offend Border so that it fills the stretched width of the Grid . This element is emitted by the TreeViewItem template, so I found that the effective way to change its properties is to target the Style in the resource dictionary of the Style element template. Yes, it is embarrassing. That Style , in turn, is set via TreeViewItem.ItemContainerStyle .

To see a (existing) behavior violation, you can comment on the part between the dashed lines:

enter image description here

You can also set these styles in some resource dictionary, instead of using the ItemContainerStyle property, as I here. I did it this way because it minimizes the amount of fix so that Border controls not related to it will not be affected. If you need a more discriminatory way of targeting this control only, you can take advantage of the fact that it has Name='Bd' .




[edit:] This solution does not use reflection! Do not be afraid of meaningless demo data - this has nothing to do with this problem; it was the easiest way to capture some hierarchical data for demonstration purposes, and the whole program was tiny.




[edit # 2:] I just realized that what the designers were trying to avoid with the 3x2 grid was the next unsightly effect (exaggerated here with a small screenshot). Therefore, if you make one of the decisions on this page, warn you about this, you may not want this:

enter image description here

+14
Jun 14 '15 at 13:10
source share

If you mean something like this screen shot

Full Width TreeViewItem http://www.bendewey.com/code/treeViewFullWidth2.png

Update As already noted, this example has a reduced indent in subparagraphs

Full Width TreeViewItem http://www.bendewey.com/code/treeViewFullWidth2a.png

Then this should help you. It is also based on http://msdn.microsoft.com/en-us/library/ms788727.aspx , you can change the TreeViewItem template to a StackPanel and set the ItemsPanel left margin to 19. Then in TreeView you set HorizontalContentAlignment = "Stretch " I am attaching the entire resource below, but here is the important part.

 <ControlTemplate TargetType="{x:Type TreeViewItem}"> <StackPanel> <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="19" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <ContentPresenter x:Name="PART_Header" Grid.Column="1" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Grid> </Border> <ItemsPresenter x:Name="ItemsHost" Margin="19,0,0,0" /> </StackPanel> <!-- Triggers --> </ControlTemplate> 

Control

 <TreeView Margin="50" HorizontalContentAlignment="Stretch"> <TreeViewItem Header="test2"/> <TreeViewItem Header="test2"> <TreeViewItem Header="sub test"/> <TreeViewItem Header="sub test2"/> </TreeViewItem> <TreeViewItem Header="test3"/> </TreeView> 

Resources

 <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> <!--================================================================= TreeViewItem ==================================================================--> <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton"> <Setter Property="Focusable" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid Width="15" Height="13" Background="Transparent"> <Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="{StaticResource GlyphBrush}" Data="M 4 0 L 8 4 L 4 8 Z"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="TreeViewItemFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Border> <Rectangle Margin="0,0,0,0" StrokeThickness="5" Stroke="Black" StrokeDashArray="1 2" Opacity="0"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="VerticalContentAlignment" Value="{Binding Path=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" Value="{StaticResource TreeViewItemFocusVisual}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <StackPanel> <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="19" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <ContentPresenter x:Name="PART_Header" Grid.Column="1" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Grid> </Border> <ItemsPresenter x:Name="ItemsHost" Margin="19,0,0,0" /> </StackPanel> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Width" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Height" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/> </MultiTrigger> <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.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 
+6
Mar 20 '09 at 23:47
source share

If you mean something like this screen shot

LineItem Hightlighting in TreeView http://www.bendewey.com/code/treeViewFullWidth.png

Then this should help you. Based on http://msdn.microsoft.com/en-us/library/ms788727.aspx you can make some changes to the TreeViewItem grid layout. Basically you delete the third column. Then in TreeView you set HorizontalContentAlignment = "Stretch". I am attaching the entire resource below, but here is the important part.

 <!-- ... --> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="19" Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <!-- ... --> 

Control

 <TreeView Margin="50" HorizontalContentAlignment="Stretch"> <TreeViewItem Header="test2"/> <TreeViewItem Header="test2"> <TreeViewItem Header="sub test"/> <TreeViewItem Header="sub test2"/> </TreeViewItem> <TreeViewItem Header="test3"/> </TreeView> 

Resources

 <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> <!--================================================================= TreeViewItem ==================================================================--> <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton"> <Setter Property="Focusable" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid Width="15" Height="13" Background="Transparent"> <Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="{StaticResource GlyphBrush}" Data="M 4 0 L 8 4 L 4 8 Z"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="TreeViewItemFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Border> <Rectangle Margin="0,0,0,0" StrokeThickness="5" Stroke="Black" StrokeDashArray="1 2" Opacity="0"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="VerticalContentAlignment" Value="{Binding Path=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" Value="{StaticResource TreeViewItemFocusVisual}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="19" Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Border> <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Width" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Height" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/> </MultiTrigger> <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.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 
+4
Mar 20 '09 at 2:13
source share

This is by far the easiest solution. Just create a rectangle, name it Hb and set its edge to -100px and you won’t see it. Set it only to Visible when you select it or hover over it. This is a hack, but you can use up to 5 levels of nested TreeViewItems (100> 19 * 5).

  <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="19" Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" VerticalAlignment="Top" Panel.ZIndex="1"/> <Rectangle x:Name="Hb" Width="Auto" Height="Auto" Grid.ColumnSpan="2" Margin="-100,0,0,0" Panel.ZIndex="-1" Visibility="Hidden" /> <Border x:Name="Bd" SnapsToDevicePixels="true" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Column="1" Panel.ZIndex="0"> <ContentPresenter x:Name="PART_Header" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" HorizontalAlignment="Stretch"/> </Border> <ItemsPresenter x:Name="ItemsHost" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Margin="19,0,0,0"/> </Grid> 
+2
Oct 26 '09 at 21:33
source share

The source of the problem when using TreeView with ItemsSource, refers to the link text , I changed the code of the TreeViewItemExtensions class:

 public static class TreeViewItemExtensions { public static int GetDepth(this TreeViewItem item) { while (GetSelectedTreeViewItemParent(item) != null) { var parent = GetSelectedTreeViewItemParent(item); if (parent != null) return parent.GetDepth() + 1; item = parent; } return 0; } public static TreeViewItem GetSelectedTreeViewItemParent(this TreeViewItem item) { DependencyObject parent = VisualTreeHelper.GetParent(item); while (!(parent is TreeViewItem || parent is TreeView)) { parent = VisualTreeHelper.GetParent(parent); } return parent as TreeViewItem; } } 
+1
Sep 24 '09 at 4:58
source share

Something like theseven7 is used to facilitate the use of bendewey code with TreeViewItems templates ...

  public static int GetDepth(this TreeViewItem item) { FrameworkElement elem = item; var parent = VisualTreeHelper.GetParent(item); var count = 0; while (parent != null && !(parent is TreeView)) { var tvi = parent as TreeViewItem; if (parent is TreeViewItem) count++; parent = VisualTreeHelper.GetParent(parent); } return count; } 
+1
Aug 6 2018-10-18T00:
source share

I did this by copying the ItemContainerStyle element with a blend, giving the name of the grid the item is placed in, and then setting the grid background.

0
Apr 10 '13 at 17:26
source share

For the XAML approach, I took one of Bendewey's solutions and broke it down a bit into a more basic solution:

In the style below, Treeview elements should be available:

 <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="19" Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <ToggleButton x:Name="Expander" Content="..." IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <Border Name="Bd" Grid.Column="1" Background="Red" Padding="3"> <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Border> <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1"/> </Grid> <!-- ADD TRIGGERS HERE --> </ControlTemplate> </Setter.Value> </Setter> </Style> 

To make it work and crash like the correct Treeview, the triggers below should allow this:

 <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Width" Value="Auto"/> </MultiTrigger.Conditions> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Height" Value="Auto"/> </MultiTrigger.Conditions> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> </MultiTrigger> <Trigger Property="IsSelected" Value="true"> <Setter TargetName="Bd" Property="Background" Value="Blue"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> </ControlTemplate.Triggers> 

Just insert the triggers in the control template. Colors / padding / design will need to be tailored to your own needs, but the above should be a very simple idea based only on XAML.

0
Sep 19 '17 at 6:41
source share



All Articles