WPF TreeView实现固定表头

1、在WPF中TreeView默认不支持固定表头的我们可以修改样式实现固定表头

  新建一个TreeListView类 然后继承TreeView代码如下

复制代码
public class TreeListView : TreeView,IDisposable
    {

        public TreeListView()
        {
           //this.Loaded += TreeListView_Loaded;
            //this.SizeChanged += TreeListView_SizeChanged;
            //SourceUpdated += TreeListView_SourceUpdated;
        }

        private void TreeListView_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {
           
        }

        double fixedColumnsWidth = 0;
        //int resizableColumnCount = 0;
        List<int> resizableColumnCount=new List<int>();
        GridViewHeaderRowPresenter gridViewHeaderRowPresenter;
        bool shub=false;
        private void TreeListView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            fixedColumnsWidth = 0;
            var treeListView = sender as TreeListView; // 将 DependencyObject 转换为具体类型
            if (treeListView != null)
            {
                double wh = treeListView.ActualWidth;
                for (int i = 0;i < treeListView.Columns.Count; i++)
                {
                    if (treeListView.Columns[i].Width > 0)
                    {
                        if (resizableColumnCount.Contains(i)==false)
                            fixedColumnsWidth += treeListView.Columns[i].Width;
                    }
                    else
                    {
                        if (resizableColumnCount.Any() == false)
                            resizableColumnCount.Add(i);
                    }
                }
                // 计算剩余空间
                 double remainingWidth = wh - fixedColumnsWidth;
                // 如果有可调整宽度的列,将剩余空间均分给它们
                if (resizableColumnCount.Any())
                {
                    double widthPerResizableColumn = remainingWidth / resizableColumnCount.Count;
                    foreach (int i in resizableColumnCount)
                    {
                        if (resizableColumnCount.Contains(i))
                        {
                            treeListView.Columns[i] .Width= widthPerResizableColumn;
                        }
                    }
                }
            }
        }
        private void TreeListView_Loaded(object sender, RoutedEventArgs e)
        {
            gridViewHeaderRowPresenter=  this.Template.FindName("HeaderPresenter", this) as GridViewHeaderRowPresenter;
            if(gridViewHeaderRowPresenter != null )
            {
                gridViewHeaderRowPresenter.PreviewMouseLeftButtonDown += GridViewHeaderRowPresenter_PreviewMouseLeftButtonDown;
                gridViewHeaderRowPresenter.PreviewMouseMove += GridViewHeaderRowPresenter_PreviewMouseMove;
                gridViewHeaderRowPresenter.PreviewMouseLeftButtonUp += GridViewHeaderRowPresenter_PreviewMouseLeftButtonUp;
            }
        }

        private void GridViewHeaderRowPresenter_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            shub=false;
        }

        private void GridViewHeaderRowPresenter_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (shub)
            {
              //var d=  e.GetPosition(gridViewHeaderRowPresenter);
              //  // 找到当前被点击的列
              //  var hitTestResult = VisualTreeHelper.HitTest(gridViewHeaderRowPresenter, d);
              //  if (hitTestResult != null)
              //  {
              //      // 获取被点击的列标题
              //      var columnHeader = hitTestResult.VisualHit as GridViewColumn;

              //      if (columnHeader != null)
              //      {
              //          var gridView = (GridView)gridViewHeaderRowPresenter.DataContext;
              //          var columns = gridView.Columns;

              //          // 检查是否是最后一列
              //          //if (columnHeader.c == columns.Last())
              //          //{
              //          //    // 禁用拖动行为
              //          //    e.Handled = true;
              //          //}
              //      }
              //  }
            }

        }

        private void GridViewHeaderRowPresenter_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            shub = true;
        }

        protected override System.Windows.DependencyObject
                           GetContainerForItemOverride()
        {
            return new TreeListViewItem();
        }

        protected override bool
                           IsItemItsOwnContainerOverride(object item)
        {
            return item is TreeListViewItem;
        }
        /// <summary>
        /// Gets or sets the collection of System.Windows.Controls.GridViewColumn 
        /// objects that is defined for this TreeListView.
        /// </summary>
        public GridViewColumnCollection Columns
        {
            get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }


        // Using a DependencyProperty as the backing store for Columns.  This enables animation, styling, binding, etc...
        public static readonly System.Windows.DependencyProperty ColumnsProperty =
            System.Windows.DependencyProperty.Register("Columns", typeof(GridViewColumnCollection),
            typeof(TreeListView),
            new PropertyMetadata(OnColumnsChanged));

        //
        //public Command PreviewMouseLeftButtonDownl
        //{
        //    get { return (Command)GetValue(PreviewMouseLeftButtonDownlProperty); }
        //    set { SetValue(PreviewMouseLeftButtonDownlProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for PreviewMouseLeftButtonDownl.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty PreviewMouseLeftButtonDownlProperty =
        //    DependencyProperty.Register("PreviewMouseLeftButtonDownl", typeof(Command), typeof(GridViewColumnCollection), new PropertyMetadata(PreviewMouseLeftButtonDownlcleck));

        //private static void PreviewMouseLeftButtonDownlcleck(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
            
        //}

        private static void OnColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // 在此处理属性更改的逻辑
            var treeListView = d as GridViewHeaderRowPresenter; // 将 DependencyObject 转换为具体类型
            if (treeListView != null)
            {
                foreach (var columnHeader in treeListView.Columns)
                {
                   // (columnHeader.).PreviewMouseLeftButtonUp += ColumnHeader_PreviewMouseLeftButtonDown;
                    //columnHeader.PreviewMouseMove += ColumnHeader_PreviewMouseMove;
                    //columnHeader.PreviewMouseLeftButtonUp += ColumnHeader_PreviewMouseLeftButtonUp;
                }

                // 在此处添加您的处理逻辑,例如通知其他控件
            }
        }

        public void Dispose()
        {
            
        }
    }

    public class TreeListViewItem : TreeViewItem
    {
        /// <summary>
        /// Item's hierarchy in the tree
        /// </summary>
        public int Level
        {
            get
            {
                if (_level == -1)
                {
                    TreeListViewItem parent =
                        ItemsControl.ItemsControlFromItemContainer(this)
                            as TreeListViewItem;
                    _level = (parent != null) ? parent.Level + 1 : 0;
                }
                return _level;
            }
        }


        protected override DependencyObject
                           GetContainerForItemOverride()
        {
            return new TreeListViewItem();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is TreeListViewItem;
        }

        private int _level = -1;
    }
复制代码

 样式如下:

复制代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:convert="clr-namespace:TreeListViewSample.Converters"
                    xmlns:local="clr-namespace:TreeListViewSample.Controls">

    <!--Converter for Indentation of items-->
    <convert:LevelToIndentConverter x:Key="LevelIndentConverter" />

    <Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="Width" Value="19"/>
        <Setter Property="Height" Value="13"/>
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border Width="19" Height="13" Background="Transparent">
                        <Border Width="9" Height="9"
                                BorderThickness="1"
                                BorderBrush="#FF7898B5"
                                CornerRadius="1"
                                SnapsToDevicePixels="true">
                            <Border.Background>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="White" Offset=".2"/>
                                        <GradientStop Color="#FFC0B7A6" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Border.Background>
                            <Path x:Name="ExpandPath"
                                  Margin="1,1,1,1"
                                  Fill="Black"
                                  Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z"/>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter Property="Data" TargetName="ExpandPath" Value="M 0 2 L 0 3 L 5 3 L 5 2 Z"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <DataTemplate x:Key="CellTemplate_Name">
        <DockPanel>
            <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" 
                      Margin="{Binding Path=Level,
                               Converter={StaticResource LevelIndentConverter},
                               RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}"
                      IsChecked="{Binding Path=IsExpanded,
                                  RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}"
                      ClickMode="Press"/>
            <!--首列绑定值-->
            <TextBlock Text="{Binding Name}"/>
        </DockPanel>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=HasItems,
                                   RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}" 
                         Value="False">
                <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

    <!--<ImageBrush x:Key="gvHeaderBackground" ImageSource="/TreeListViewSample;component/Images/list_header_bk.png" />-->
    <Style x:Key="gvColumnHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
        <Style.Setters>
            <Setter Property="Height" Value="34" />
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="LightBlue" Offset="0" />
                        <GradientStop Color="Gray" Offset="1" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>

    <!--<GridViewColumnCollection x:Key="gvColumns">
        <GridViewColumn Header="姓名"
                        CellTemplate="{StaticResource CellTemplate_Name}" Width="150" />
        <GridViewColumn Header="年龄" 
                        DisplayMemberBinding="{Binding Age}" Width="80" />
        <GridViewColumn Header="性别" 
                        DisplayMemberBinding="{Binding Sex}" Width="80" />
        <GridViewColumn Header="职务"
                        DisplayMemberBinding="{Binding Duty}" Width="100" />
    </GridViewColumnCollection>-->
    
    <!--交替行样式-->
    <AlternationConverter x:Key="conBack">
        <SolidColorBrush>YellowGreen</SolidColorBrush>
        <SolidColorBrush>SkyBlue</SolidColorBrush>
    </AlternationConverter>

    <Style TargetType="{x:Type local:TreeListViewItem}">
        <Setter Property="FontSize" Value="13" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        <Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
        <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},
                Path=(local:TreeListView.AlternationIndex),
                Converter={StaticResource conBack}}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:TreeListViewItem}">
                    <StackPanel>
                        <Border x:Name="outerBorder"
                                BorderThickness="0,0,0,1"
                                BorderBrush="#FFFFFFFD"
                                Margin="0" Padding="0" Height="30"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                SnapsToDevicePixels="True">
                            <Border x:Name="innerBorder"
                                    BorderThickness="0,0,0,1"
                                    BorderBrush="#FFC6C6C6"
                                    Background="{TemplateBinding Background}"
                                    Padding="{TemplateBinding Padding}"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    SnapsToDevicePixels="True">
                                <GridViewRowPresenter x:Name="PART_Header"
                                                  Content="{TemplateBinding Header}"         
                                                  Columns="{Binding Columns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeListView}}"
                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                        </Border>
                        <ItemsPresenter x:Name="ItemsHost" />
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <!--<Trigger Property="local:TreeListView.AlternationIndex" Value="1">    Columns="{Binding Columns, 
                    RelativeSource={RelativeSource Mode=FindAncestor, 
                    AncestorType=local:TreeListView}"
                            <Setter Property="Background" Value="#FFE1E4F7"></Setter>
                        </Trigger>-->
                        <Trigger Property="IsMouseOver" Value="true" SourceName="innerBorder">
                            <Setter Property="Foreground" Value="White"/>
                            <Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/>
                        </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}}"/>-->
                            <Setter Property="Foreground" Value="White"/>
                            <Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/>
                        </Trigger>
                        <Trigger Property="IsExpanded" Value="false">
                            <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="innerBorder" Property="Background"
                                    Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        </MultiTrigger>
                        <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>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type local:TreeListView}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:TreeListView}">
                    <!--Create a standard border around the 'TreeListView'.-->
                    <Border Padding="{TemplateBinding Padding}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}">
                        <!--ScrollViewer providing horizontal scrolling functionality 
                                for both, content and headers.-->
                        <!--<ScrollViewer 
                                      HorizontalScrollBarVisibility="Auto" CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
                                              VerticalScrollBarVisibility="Auto"  Focusable="False">-->
                        <DockPanel>
                            <!--The header row.  PreviewMouseLeftButtonDown="{Binding }" PreviewMouseMove=""  PreviewMouseLeftButtonUp=""-->
                            <GridViewHeaderRowPresenter DockPanel.Dock="Top" SnapsToDevicePixels="True" x:Name="HeaderPresenter"
                                                            Columns="{Binding Columns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeListView}}"
                                                            ColumnHeaderContainerStyle="{StaticResource gvColumnHeaderStyle}"
                                                            >
                            </GridViewHeaderRowPresenter>
                            <!--ScrollViewer providing vertical scrolling Columns="{StaticResource gvColumns}"
                                        functionality for the content.-->
                            <ScrollViewer HorizontalScrollBarVisibility="Auto" CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
                                              VerticalScrollBarVisibility="Auto"  Focusable="False">
                                <!--ItemsPresenter containg the content.-->
                                <ItemsPresenter />
                            </ScrollViewer>
                        </DockPanel>
                        <!--</ScrollViewer>-->
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!--<Style TargetType="GridViewHeaderRowPresenter">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="Background" Value="LightBlue"/>
        --><!-- 修改背景颜色 --><!--
        <Setter Property="Foreground" Value="Black"/>
        --><!-- 修改字体颜色 --><!--
        <Setter Property="FontSize" Value="14"/>
        --><!-- 修改字体大小 --><!--
        <Setter Property="FontWeight" Value="Bold"/>
        --><!-- 修改字体粗细 --><!--
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Height" Value="30"/>
        --><!-- 修改行高 --><!--
        <Setter Property="Padding" Value="8"/>
        --><!-- 修改内边距 --><!--
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:TypeGridViewHeaderRowPresenter}">
                    <GridViewHeaderRowPresenterColumns="{TemplateBindingGridView.ColumnHeaderContainerStyle}"
                                      Columns="{TemplateBindingGridView.Columns}"
                                      ColumnHeaderContextMenu="{TemplateBindingGridView.ColumnHeaderContextMenu}"
                                      ColumnHeaderToolTip="{TemplateBindingGridView.ColumnHeaderToolTip}"
                                      KeyboardNavigation.TabNavigation="Local"
                                      SnapsToDevicePixels="{TemplateBindingSnapsToDevicePixels}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>-->
</ResourceDictionary>
复制代码

添加测试数据的代码如下

复制代码
namespace TreeListViewSample.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<Staff> _StaffList = new ObservableCollection<Staff>();

        public ObservableCollection<Staff> StaffList
        {
            get { return _StaffList; }
            set
            {
                _StaffList = value;
                this.RaisePropertyChanged("StaffList");
            }
        }

        public MainViewModel()
        {
            for (int i = 0; i < 10000; i++)
            {
                Staff staff = new Staff()
                {
                    Name = "张三",
                    Age = 30,
                    Sex = "",
                    Duty = "经理",
                    IsExpanded = true
                };
                Staff staff2 = new Staff()
                {
                    Name = "张三1",
                    Age = 21,
                    Sex = "",
                    Duty = "员工",
                    IsExpanded = true
                };
                Staff staff3 = new Staff()
                {
                    Name = "张三11",
                    Age = 21,
                    Sex = "",
                    Duty = "员工"
                };
                staff2.StaffList.Add(staff3);
                staff3 = new Staff()
                {
                    Name = "张三22",
                    Age = 21,
                    Sex = "",
                    Duty = "员工"
                };
                staff2.StaffList.Add(staff3);
                staff.StaffList.Add(staff2);
                staff2 = new Staff()
                {
                    Name = "张三2",
                    Age = 22,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                staff2 = new Staff()
                {
                    Name = "张三3",
                    Age = 23,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                StaffList.Add(staff);

                staff = new Staff()
                {
                    Name = "李四",
                    Age = 31,
                    Sex = "",
                    Duty = "副经理"
                };
                staff2 = new Staff()
                {
                    Name = "李四1",
                    Age = 24,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                staff2 = new Staff()
                {
                    Name = "李四2",
                    Age = 25,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                staff2 = new Staff()
                {
                    Name = "李四3",
                    Age = 26,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                StaffList.Add(staff);

                staff = new Staff()
                {
                    Name = "王五",
                    Age = 32,
                    Sex = "",
                    Duty = "组长"
                };
                staff2 = new Staff()
                {
                    Name = "王五1",
                    Age = 27,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                staff2 = new Staff()
                {
                    Name = "王五2",
                    Age = 28,
                    Sex = "",
                    Duty = "员工"
                };
                staff.StaffList.Add(staff2);
                StaffList.Add(staff);
            }        
        }

        public void ChangeNode1Value()
        {
            foreach (Staff staff in this.StaffList)
            {
                staff.Age += 1;
                staff.Sex = staff.Sex == "" ? "" : "";
            }
        }

        public void ChangeNode2Value()
        {
            foreach (Staff staff in this.StaffList)
            {
                foreach (Staff staff2 in staff.StaffList)
                {
                    staff2.Age += 1;
                    staff2.Sex = staff2.Sex == "" ? "" : "";
                }
            }
        }
    }
}
复制代码

最后 这里我们开启了虚拟化添加再多数据界面也不会卡顿

复制代码
    <local:TreeListView x:Name="treeList" 
                             ScrollViewer.CanContentScroll="True"
                                 VirtualizingStackPanel.IsVirtualizing="True"
                    VirtualizingStackPanel.VirtualizationMode="Recycling"
                            Background="#FFE9E9E9" BorderBrush="#FF96DFFF"
                            AlternationCount="2" ItemsSource="{Binding StaffList}">
            <local:TreeListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel x:Name="ItemsHost" IsItemsHost="True" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Height="Auto"/>
                </ItemsPanelTemplate>
            </local:TreeListView.ItemsPanel>
            <local:TreeListView.Columns>
                <GridViewColumnCollection>
                    <GridViewColumn Header="姓名" 
                        CellTemplate="{StaticResource CellTemplate_Name}" Width="200" >
                    </GridViewColumn>
                    <GridViewColumn Header="年龄" 
                        DisplayMemberBinding="{Binding Age}" Width="80" />
                    <GridViewColumn Header="性别" 
                        DisplayMemberBinding="{Binding Sex}" Width="80" />
                    <GridViewColumn Header="职务"
                        DisplayMemberBinding="{Binding Duty}" Width="150"/>
                </GridViewColumnCollection>
            </local:TreeListView.Columns>
            <local:TreeListView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding StaffList}" />
            </local:TreeListView.ItemTemplate>
        </local:TreeListView>
复制代码

最后效果

 

posted @   ¥东方不败  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示