You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TreeViewItem中的TextBlock填充其完整高度?

解决TreeViewItem中TextBlock高度填充问题

你遇到的这个问题我之前也碰到过——TextBlock能填满TreeView的宽度,但始终没法撑满TreeViewItem的高度,导致点击Item边缘区域时MouseDown事件不触发。核心原因其实不在ItemsPanel里的StackPanel,而是TreeViewItem的默认ControlTemplate限制了内容的垂直拉伸,下面是具体的解决方法:

步骤1:重写TreeViewItem的ControlTemplate

我们需要修改TreeViewItem的默认样式,让内部的内容容器垂直方向完全拉伸,这样TextBlock才有机会填满整个Item高度。把这个样式添加到TreeView的Resources中:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" MinWidth="19" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <!-- 展开/折叠按钮 -->
                    <ToggleButton x:Name="Expander" 
                                  Style="{StaticResource ExpandCollapseToggleStyle}"
                                  IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                  ClickMode="Press"/>
                    <!-- 关键:设置Border的VerticalAlignment为Stretch,让内容区域填满Item高度 -->
                    <Border x:Name="Bd" 
                            Grid.Column="1"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Padding="{TemplateBinding Padding}"
                            VerticalAlignment="Stretch">
                        <ContentPresenter x:Name="PART_Header"
                                          ContentSource="Header"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="Stretch"/>
                    </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="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>

步骤2:调整HierarchicalDataTemplate中的TextBlock

接着修改你的TextBlock配置,确保它的垂直对齐和内容对齐都设为Stretch,同时去掉可能引发循环依赖的ActualHeight绑定:

<HierarchicalDataTemplate DataType="{x:Type local:TreeGTOViewModel}" ItemsSource="{Binding Children}">
    <TextBlock VerticalAlignment="Stretch"
               VerticalContentAlignment="Center"
               Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeView}}, Path=ActualWidth}"
               MouseDown="TextBlock_MouseDown"
               Tag="{Binding Uri}"
               Text="{Binding Title}" />
</HierarchicalDataTemplate>

为什么之前的方法没用?

  • 你尝试的VerticalAlignment="Stretch"无效,是因为TreeViewItem默认模板里的ContentPresenter没有设置垂直拉伸,TextBlock根本没有机会填满整个Item高度。
  • 绑定TreeViewItem的ActualHeight会引发布局循环依赖——TextBlock的高度依赖Item高度,Item高度又依赖TextBlock高度,最终导致TreeView异常。
  • ItemsPanel里的StackPanel其实没问题,它的垂直布局不会影响子元素的高度拉伸,只要父容器允许即可。

这样修改后,TextBlock就会填满TreeViewItem的整个高度,点击Item的任何区域都会触发MouseDown事件,同时也能保留你原来的宽度填充和Material Design悬停阴影效果。

内容的提问来源于stack exchange,提问作者Robert Harvey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:17:09