突出显示WPF中的整个TreeViewItem行

如果我设置TreeViewItem背景,它只会突出标题。 我怎样才能突出整个行?

我发现一个职位几乎解决了一个问题http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b04f73e2-0b10-4d97-a6da-64df2e30c21d/

但是有一些问题:1,没有突出整个行2.树上有Vista的XP风格。 我喜欢它在Vista上看起来是一样的,但如果用户将主题改为XP,应该是XP的方式。 这么多XAML …

任何想法,我应该找什么?

在这里,我们走了,第三次魅力。 如果你想要的东西看起来像这样。

全宽度TreeView

这一个需要更多的工作。 我确信有很多方法可以做到这一点,但是这种方法使用长度转换器和TreeViewItem扩展方法来获得深度。 这两者都紧密结合到TreeViewItem可视化树,所以如果你开始搞乱模板,那么你可能会遇到麻烦。 再次,这里是重要的部分,下面是完整的代码。

<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> 

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(); } } 

控制

 <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> 

完整的TreeViewItem样式

 <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> 

TreeViewItem标题不会伸展?

发生此问题是因为WPF的TreeViewItem的默认模板设置为由2行Grid 3列。 第一行是“标题”(实际上是一个Border ),第二行是为ItemsPresenter 。 当你点击占据Grid的第零列的小三angular形时,为了完成树的展开,两行可视化或隐藏。

两行实际上只需要一个额外的列。 例如,在第二行中,我们必须在col-0,第一行没有任何内容,因为当IsExpanded为真时,空白部分应该缩进。 但是,当我们注意到以col-1,第1 ItemsPresenter基础的ItemsPresenter指定了Grid.ColumnSpan=2时,这个谜就开始了。

不幸的是,在第一行中,包含标题的Border被设置为Grid.Column=1 …但是没有ColumnSpan。 由于Grid的col-2有Width=*这意味着标题/边框不会水平拉伸。

换句话说,我看起来像三列网格devise没有任何目的,除了专门为了防止头伸展。 据我所知,一个简单的2×2排列会更灵活[编辑:见脚注#2],通过常规的WPFalignment机制支持全拉伸 “锯齿状”标题非拉伸。

理想情况下,我们将Grid更改为只有2个列,而不是3个。由于这不是那么容易,相反,我们将使标题跨2列,就像ItemsPresenter一样。

好的,这是一个小而完整的自包含(仅限XAML)工作程序 ,它演示并修复了以下问题:

 <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> 

如果你运行这个程序,如图所示,你会看到类似的东西。 这是固定的行为,它允许您重新完全控制TreeViewItem标头的拉伸行为:

在这里输入图像说明

在XAML源代码中注意BEGIN / END部分的虚线。 基本上,我只是在违规Border上设置Grid.ColumnSpan=2 ,以便填充Grid的拉伸宽度。 该元素由TreeViewItem模板发出,因此我发现改变其属性的有效方法是通过项目模板的Style的资源字典中的目标Style 。 是的,令人困惑。 该Style依次通过TreeViewItem.ItemContainerStyle设置。

要查看(现有的)破坏的行为,可以注释掉虚线之间的部分:

在这里输入图像说明

您也可以在某些资源字典中设置这些样式,而不是像在这里那样使用ItemContainerStyle属性。 我这样做是因为它最小化了修复的范围,所以不相关的Border控件不会受到影响。 如果你确实需要一个更具辨别性的方法来定位这个控件,那么你可能会利用它的Name='Bd'的事实。


这个解决scheme不使用reflection! 不要被无意义的演示数据吓倒 – 这与这个问题无关; 只是为了演示的目的而抓取一些分层数据的最简单的方法,同时保持整个程序很小。


我刚刚意识到,devise者试图通过3×2网格布局来避免以下难看的效果(在这里通过缩小的屏幕截图夸大了这一点)。 因此,如果您采用本页面的解决scheme之一,应预先警告您可能不需要这样做:

在这里输入图像说明

如果你的意思是这样的截图

全宽TreeViewItem code/treeViewFullWidth2.png

更新如上所述,这个例子有在子项上缩进的失败

全宽TreeViewItem code/treeViewFullWidth2a.png

那么这应该可以帮到你。 它也基于http://msdn.microsoft.com/en-us/library/ms788727.aspx您可以将TreeViewItem的模板更改为StackPanel并将ItemsPanel左边距设置为19.然后在TreeView中将Horizo​​ntalContentAlignment = “伸展”。 我附上下面的整个资源,但这里是重要的一部分。

 <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> 

控制

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

资源

 <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> 

如果你的意思是这样的截图

在TreeView中LineItem Hightlighting code/treeViewFullWidth.png

那么这应该可以帮到你。 它基于http://msdn.microsoft.com/en-us/library/ms788727.aspx,您可以对TreeViewItem的网格布局进行一些更改。; 基本上你删除第三列。 然后在TreeView中设置Horizo​​ntalContentAlignment =“Stretch”。 我附上下面的整个资源,但这里是重要的一部分。

 <!-- ... --> <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> <!-- ... --> 

控制

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

资源

 <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> 

这是迄今为止最简单的解决scheme。 只要创build一个矩形,将其称为Hb,并将其边距设置为-100px并且不可见。 只有在您选定或将鼠标hover后才将其设置为“可见”。 这是一个黑客,但你最好5层嵌套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> 

当使用TreeView与ItemsSource时,问题的根源在于链接文本 ,我已经更改了TreeViewItemExtensions类的一些代码:

 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; } } 

使用类似theseven7的东西,以方便使用bendewey的代码与模板TreeViewItems …

  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; } 

我通过使用混合复制ItemContainerStyle来pipe理这个事情,给项目放置的网格命名,然后设置网格的背景。

对于仅采用XAML的方法,我采用了Bendewey的解决scheme之一,并将其​​分解为更基本的解决scheme:

下面的样式应该允许Treeview项目跨越:

 <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> 

为了让它像适当的Treeview一样运行和崩溃,下面的触发器应该允许这样做:

 <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> 

只需在控制模板中嵌套触发器即可。 颜色/填充/devise将需要调整,以适应您自己的需求,但上述应该是一个基于XAML的基础上的一个非常基本的想法。