Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to highlight entire row in WPF TreeView

I want to adapt the default WPF TreeView/TreeViewItem template, so that the entire row can be highlighted, as shown in the image:

enter image description here

However, I've tried several templates from googling, but none of them can really make the effects, some wrong answers were even marked as correct...

There was an answer in codeflow which seems to work, but it add extra C# code, or didn't need extra code but not working perfectly.

I don't want to add extra C# code, but only change the default template. Anyone have any good ideas?

Thanks a lot!

----EDIT----

@Nick, after using your template, it is shown like this,

first, it didn't highlight the "entire" row, by "entire" I mean the widest width of the tree.

second, it highlighted extra areas including the children.

enter image description here

like image 861
RainCast Avatar asked Dec 10 '14 10:12

RainCast


1 Answers

I recently had to do something similar and though the question is quite old, figured others who stumble upon this page like I did might be able to get something from my solution.

I also edited the ControlTemplate, much like how Tim described in the comments. I grouped the "Expander" toggle button and the "Bd" border controls to a single grid that stretches across the full width of the TreeView. Then under the IsSelected trigger, I set the highlight to the newly created grid instead of the border.

Here is the TreeView's ControlTemplate with my edits:

<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="19" Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <!-- created ItemRowGrid to contain both togglebutton and border -->
    <Grid x:Name="ItemRowGrid" Grid.ColumnSpan="3" Margin="1.5,0,0,0">
        <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}" HorizontalAlignment="Left" d:LayoutOverrides="Width, LeftMargin, RightMargin"/>
        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" Margin="17.5,0,-17.5,0">
            <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>
    </Grid>
    <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
    <Trigger Property="IsExpanded" Value="false">
        <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
    </Trigger>
    <Trigger Property="HasItems" Value="false">
        <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
    </Trigger>
    <Trigger Property="IsSelected" Value="true">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
        <!-- setting highlight target to created ItemRowGrid instead of border -->
        <Setter Property="Background" TargetName="ItemRowGrid" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
    </Trigger>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="true"/>
            <Condition Property="IsSelectionActive" Value="false"/>
        </MultiTrigger.Conditions>
        <Setter Property="Background" TargetName="Bd" 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>

It is not exactly the way the OP asked for because the highlight for the "children" rows start with an indent. But it does properly highlight each row without including sub-items.

like image 123
yushi Avatar answered Oct 13 '22 08:10

yushi