带我装逼带我飞 发表于 2024-4-2 14:49:13

WPF实现树形表格控件(TreeListView)

前言
  本文将探讨如何利用WPF框架实现树形表格控件,该控件不仅能够有效地展示复杂的层级数据,还能够提供丰富的个性化定制选项。我们将介绍如何使用WPF提供的控件、模板、布局、数据绑定等技术来构建这样一个树形表格。
一、运行效果
1.1默认样式

1.2 自定义样式

二、代码实现
2.1 创建自定义控件(TreeListView)
      新建一个继承自TreeView的控件,并定义一个类型为ViewBase的View依赖属性,用于在代码中指定列。
public class TreeListView : TreeView
{
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>public ViewBase View
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>{
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>get { return (ViewBase)GetValue(ViewProperty); }
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>set { SetValue(ViewProperty, value); }
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>}

<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>public static readonly DependencyProperty ViewProperty =
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>DependencyProperty.Register("View", typeof(ViewBase), typeof(TreeListView));
}2.2 在TreeListView控件模板中处理列头
   为了在TreeListView中显示列头,需要在合适的位置添加GridViewHeaderRowPresenter控件,并在Columns属性上绑定我们之前定义的View.Columns属性。下面我们首先来分析TreeView控件模板的代码。
<ControlTemplate TargetType="{x:Type TreeView}">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ItemsPresenter/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></ScrollViewer>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Border>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsEnabled" Value="false">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Trigger>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Trigger>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></ControlTemplate.Triggers>
</ControlTemplate>      通过以上代码我们可以看出,只要将GridViewHeaderRowPresenter控件添加到ScrollViewer控件上面即可实现列头功能,但这样会有一个问题,那就是内容宽度超出控件宽度后,鼠标拖动横向滚动条时列头不会跟随下方的数据列表一起滚动。为解决这个问题我们需要将GridViewHeaderRowPresenter放置到ScrollViewer控件模板中,以下为完整代码。
2.3 在TreeListViewItem模板中处理子项的展开和收缩
      新建一个继承自TreeViewItem的类,命名为TreeListViewItem(如有个性化需求,可以在该类中处理),编辑控件模板,在模板中添加以下代码。
    此处的核心在于模板中添加了GridViewRowPresenter控件,并在Columns属性上绑定了我们之前定义的View.Columns属性,这样就可以在每一行上面显示列数据。还有一个关键点是ItemsPresenter,它用于显示子项数据,此处命名为ItemsHost,它由属性触发器中的代码来控件展开和收起。以下是属性触发器代码。
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>2.4 在单元格模板中控件子项的展开与收起
   为了达到展开和收起的效果,需要在首列的单元格中控制TreeListViewItem的IsExpanded属性。以下为完整代码。
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>其关键代码为
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource AncestorType={x:Type TreeListViewItem}}}"2.5 控件使用
<ControlTemplate TargetType="{x:Type TreeView}">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ItemsPresenter/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></ScrollViewer>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Border>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsEnabled" Value="false">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Trigger>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></Trigger>
<Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger></ControlTemplate.Triggers>
</ControlTemplate><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger><Trigger Property="IsExpanded" Value="false">
    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger> 
 技术交流群  联系方式
来源:https://www.cnblogs.com/qushi2020/p/18109923
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: WPF实现树形表格控件(TreeListView)