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

如何用WPF实现类似任务管理器的树形列表样式?

WPF实现任务管理器风格树形列表的方案

针对你需要的任务管理器风格树形列表(嵌套子进程、整行悬停高亮、列对齐、保留折叠箭头),结合.NET 4.7.1的限制,给你几个关键实现方向和具体代码参考:

1. 重写TreeViewItem模板,解决整行拉伸与高亮问题

你之前设置HorizontalContentAlignment="Stretch"没生效,是因为默认TreeViewItem的ControlTemplate里,内容容器(Border、ContentPresenter)没有继承拉伸属性,必须重写模板才能让内容占满整个TreeView宽度,同时添加悬停高亮逻辑:

<!-- 自定义TreeViewItem样式 -->
<Style x:Key="ProcessTreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Height" Value="28"/> <!-- 统一行高,和任务管理器一致 -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <Grid HorizontalAlignment="Stretch">
                    <!-- 展开/折叠箭头 -->
                    <ToggleButton x:Name="Expander" 
                                  Style="{StaticResource ExpandCollapseToggleStyle}"
                                  IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                  ClickMode="Press"
                                  Margin="0,0,5,0"/>
                    <!-- 内容容器,负责整行高亮 -->
                    <Border x:Name="ItemBorder" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="0"
                            HorizontalAlignment="Stretch"
                            Margin="20,0,0,0"> <!-- 缩进,对应箭头宽度 -->
                        <ContentPresenter x:Name="HeaderPresenter"
                                          ContentSource="Header"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          SnapsToDevicePixels="True"/>
                    </Border>
                    <!-- 子项容器 -->
                    <ItemsPresenter x:Name="ChildItemsHost"
                                    Margin="20,0,0,0"
                                    Visibility="Collapsed"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <!-- 展开/折叠显示子项 -->
                    <Trigger Property="IsExpanded" Value="True">
                        <Setter TargetName="ChildItemsHost" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <!-- 鼠标悬停整行高亮 -->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="ItemBorder" Property="Background" Value="#FFE0F0FF"/>
                    </Trigger>
                    <!-- 选中状态样式(可选) -->
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="ItemBorder" Property="Background" Value="#FFCCE5FF"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- 自定义展开/折叠箭头样式 -->
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Focusable" Value="False"/>
    <Setter Property="Width" Value="16"/>
    <Setter Property="Height" Value="16"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Grid Width="16" Height="16" Background="Transparent">
                    <Path x:Name="ArrowPath"
                          Data="M0,4 L8,4 L8,0 L12,6 L8,12 L8,8 L0,8 Z"
                          Fill="#666"
                          HorizontalAlignment="Center"
                          VerticalAlignment="Center"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="ArrowPath" Property="Data" Value="M0,6 L6,6 L6,0 L12,6 L6,12 L6,6 L0,6 Z"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="ArrowPath" Property="Fill" Value="#000"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

2. 构建列对齐的树形项布局

TreeView本身没有表头,所以需要单独做一个表头Grid,和每个TreeViewItem里的内容Grid使用相同的列宽设置,确保表头与内容对齐。如果需要支持动态调整列宽,可以用SharedSizeGroup绑定列:

<!-- 表头区域 -->
<Grid Margin="0,0,0,6">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="220" SharedSizeGroup="ProcessNameCol"/>
        <ColumnDefinition Width="100" SharedSizeGroup="PIDCol"/>
        <ColumnDefinition Width="180" SharedSizeGroup="MemoryCol"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="进程名称" FontWeight="Bold" Margin="25,2,0,2"/> <!-- 留箭头位置的缩进 -->
    <TextBlock Grid.Column="1" Text="PID" FontWeight="Bold" Margin="0,2,5,2" HorizontalAlignment="Right"/>
    <TextBlock Grid.Column="2" Text="内存使用" FontWeight="Bold" Margin="0,2,5,2" HorizontalAlignment="Right"/>
</Grid>

<!-- 树形列表区域 -->
<TreeView ItemsSource="{Binding RootProcesses}"
          ItemContainerStyle="{StaticResource ProcessTreeViewItemStyle}"
          Background="White"
          BorderThickness="0">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding ChildProcesses}">
            <!-- 每个树形项的内容Grid,列与表头完全对应 -->
            <Grid HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="ProcessNameCol"/>
                    <ColumnDefinition SharedSizeGroup="PIDCol"/>
                    <ColumnDefinition SharedSizeGroup="MemoryCol"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Name}" Margin="5,2"/>
                <TextBlock Grid.Column="1" Text="{Binding Id}" Margin="0,2,5,2" HorizontalAlignment="Right"/>
                <TextBlock Grid.Column="2" Text="{Binding MemoryUsage}" Margin="0,2,5,2" HorizontalAlignment="Right"/>
            </Grid>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

3. 关键注意事项

  • 列对齐:使用SharedSizeGroup可以让表头和内容的列自动同步宽度,即使调整窗口大小也能保持对齐;如果不需要动态同步,直接设置固定宽度也可以。
  • 缩进控制:TreeViewItem模板里的Margin="20,0,0,0"是子项的缩进量,和箭头的宽度匹配,确保树形结构整齐。
  • .NET 4.7.1兼容性:所有用到的XAML特性(ControlTemplate、HierarchicalDataTemplate、SharedSizeGroup)在.NET 4.7.1中都完全支持,不需要额外依赖。
  • 数据结构:你的ViewModel需要包含树形结构,比如一个ProcessViewModel类,包含Name、Id、MemoryUsage属性,以及ChildProcesses集合属性。

内容的提问来源于stack exchange,提问作者Devak Nanda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:24:56