C# WPF TreeView用法实例解析

概述

    TreeView是常用的树状列表,在项目开发中也时常会用到,这节主要讲解treeview在wpf的基本用法!

结果演示:

e7799b41b8d393723536378219c0097e.gif

代码讲解

    前台xaml:

<UserControl x:Class="Caliburn.Micro.Hello.Views.TreeViewView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Caliburn.Micro.Hello.Views" 
             xmlns:self="clr-namespace:Caliburn.Micro.Hello.ViewModels" 
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" 
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
              xmlns:cal="http://www.caliburnproject.org" 
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>


        <dxg:TreeListControl 
            ItemsSource="{Binding EmployeeDepartments}" 
            SelectedItem="{Binding CurrentSelectedItem}" Grid.Column="0" >
            <dxg:TreeListControl.View>
                <dxg:TreeListView
                            AllowColumnFiltering="False"
                            AllowConditionalFormattingMenu="False"
                            AllowFixedColumnMenu="False"
                            AllowRecursiveNodeChecking="True"
                            AutoWidth="True"
                            FetchSublevelChildrenOnExpand="False"
                            IsColumnMenuEnabled="False"
                            IsRowCellMenuEnabled="True"
                            IsTotalSummaryMenuEnabled="False"
                            KeyFieldName="Id"
                            ParentFieldName="ParentId"
                            ShowNodeImages="True"
                            ShowSearchPanelMode="Always">
                </dxg:TreeListView>
            </dxg:TreeListControl.View>
            <dxg:TreeListColumn
                        AllowEditing="False"
                        FieldName="Employees.Name"
                        Header="{Binding TreeTitle}" />
        </dxg:TreeListControl>


        <TreeView
                                    Grid.Column="1"
                                    Margin="10,15,10,10"
                                    ItemsSource="{Binding EmployeeDepartments}">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" />
            </TreeView.ItemContainerStyle>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type self:EmployeeDepartment}" ItemsSource="{Binding Employees}">
                    <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                        <CheckBox IsChecked="True"/>
                        <TextBlock
                                                    VerticalAlignment="Center"
                                                    FontSize="14"
                                                    Text="{Binding Name}"
                                                    TextTrimming="CharacterEllipsis" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
        <!--最简洁写法-->
        <TreeView Grid.Column="0" Grid.Row="1" ItemsSource="{Binding EmployeeDepartments}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate  ItemsSource="{Binding Employees}">
                    <StackPanel>
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>


        <TreeView Grid.Column="1" Grid.Row="1" ItemsSource="{Binding nodesCollection}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate  ItemsSource="{Binding ChildNodes}">
                    <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                        <!--<dx:SimpleButton Glyph="{dx:DXImage Images/Arrows/Next_16x16.png}"/>-->
                        <CheckBox IsChecked="{Binding IsChecked}" 
                                  cal:Message.Attach="[Event Click]=[Action CheckBox_Click($source,$eventArgs)]"  />
                        <TextBlock   
                                                    VerticalAlignment="Center"
                                                    FontSize="14"
                                                    Text="{Binding NodeName}"
                                                    TextTrimming="CharacterEllipsis" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</UserControl>

后台cs代码:

using PropertyChanged;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;


namespace Caliburn.Micro.Hello.ViewModels
{
    public class TreeViewViewModel :  Screen, IViewModel
    {
        public TreeViewViewModel()
        {
            DisplayName = "TreeView";
            EmployeeDepartments = Departments.GetDepartments();


            //方法1
            //nodes = new List<TreeNode>()
            //{
            //    new TreeNode(){ ParentID = 0,NodeID = 1,NodeName = "Chapter1"},
            //     new TreeNode(){ ParentID = 0,NodeID = 2,NodeName = "Chapter2"},
            //      new TreeNode(){ ParentID = 0,NodeID = 3,NodeName = "Chapter3"},
            //       new TreeNode(){ ParentID = 1,NodeID = 4,NodeName = "Section1.1"},
            //        new TreeNode(){ ParentID = 1,NodeID = 5,NodeName = "Section1.2"},
            //            new TreeNode(){ ParentID = 2,NodeID = 6,NodeName = "Section2.1"},
            //     new TreeNode(){ ParentID = 3,NodeID = 7,NodeName = "Section3.1"},
            //      new TreeNode(){ ParentID = 6,NodeID = 8,NodeName = "SubSection2.1.1"},
            //       new TreeNode(){ ParentID = 6,NodeID = 9,NodeName = "SubSection2.1.2"},
            //        new TreeNode(){ ParentID = 2,NodeID = 10,NodeName = "Section2.2"},
            //         new TreeNode(){ ParentID = 3,NodeID = 11,NodeName = "Section3.2"},
            //};
            //nodes = getNodes(0,nodes);


            //方法2 
            nodesCollection = new ObservableCollection<TreeNode>()
            {
               new TreeNode()
               {
                   NodeName = "中国人",
                   ChildNodes = new ObservableCollection<TreeNode>()
                   {
                       new TreeNode(){ NodeName = "李嘉诚"},
                       new TreeNode()
                       {
                           NodeName = "王健林",
                           ChildNodes = new ObservableCollection<TreeNode>()
                           {
                               new TreeNode(){ NodeName = "68岁"},
                               new TreeNode(){ NodeName = "一个儿子"},
                           }
                       },
                   }
               },
                new TreeNode()
               {
                   NodeName = "外国人",
                   ChildNodes = new ObservableCollection<TreeNode>()
                   {
                       new TreeNode()
                       {
                           NodeName = "马斯克",
                           ChildNodes = new ObservableCollection<TreeNode>()
                           {
                               new TreeNode(){ NodeName = "51岁"},
                               new TreeNode(){ NodeName = "10个老婆"},
                           }
                       },
                   }
               }
            };
        }
        public List<EmployeeDepartment> EmployeeDepartments { get; set; }


        public List<TreeNode> nodes { get; set; }
        public ObservableCollection<TreeNode> nodesCollection { get; set; }
        //private List<TreeNode> getNodes(int parentID, List<TreeNode> nodes)
        //{
        //    List<TreeNode> mainNodes = nodes.Where(x => x.ParentID == parentID).ToList();
        //    List<TreeNode> otherNodes = nodes.Where(x => x.ParentID != parentID).ToList();
        //    foreach (TreeNode node in mainNodes)
        //        node.ChildNodes = getNodes(node.NodeID, otherNodes);
        //    return mainNodes;
        //}
        public void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            CheckBox checkBox;
            if (sender is CheckBox)
            {
                checkBox = sender as CheckBox;
            }
            else
            {
                return;
            }


            //SetIsChecked(nodesCollection);
            foreach (var childNode in nodesCollection)
            {
                //SetIsChecked(childNode, checkBox.IsChecked);
                SetIsChecked(childNode);
            }
        }


        //public void SetIsChecked(ObservableCollection<TreeNode> childNodes)
        //{
        //    foreach (var childNode in childNodes)
        //    {
        //        if(!childNode.IsChecked)
        //        {
        //            foreach (var child in childNode.ChildNodes)
        //            {
        //                child.IsChecked = false;
        //                SetIsChecked(child.ChildNodes);
        //            }
        //        }
        //        else
        //        {
        //            SetIsChecked(childNode.ChildNodes);
        //        }
        //    }
        //}


        public void SetIsChecked(TreeNode treeNode)
        {
            foreach (var child in treeNode.ChildNodes)
            {
                if (!treeNode.IsChecked)
                {
                    child.IsChecked = false;
                }
                SetIsChecked(child);
            }
        }


    }


    public static class Departments
    {
        public static List<EmployeeDepartment> GetDepartments()
        {
            List<EmployeeDepartment> departments = new List<EmployeeDepartment>();
            departments.Add(new EmployeeDepartment("Management", new Employee[] {
                new Employee(0, "Gregory S. Price")
            }));
            departments.Add(new EmployeeDepartment("Marketing", new Employee[] {
                new Employee(1, "Irma R. Marshall"),
                new Employee(2, "Brian C. Cowling"),
                new Employee(3, "Thomas C. Dawson"),
                new Employee(4, "Bryan R. Henderson"),
            }));
            departments.Add(new EmployeeDepartment("Operations", new Employee[] {
                new Employee(5, "John C. Powell"),
                new Employee(6, "Harold S. Brandes"),
                new Employee(7, "Jan K. Sisk"),
                new Employee(8, "Sidney L. Holder"),
            }));
            departments.Add(new EmployeeDepartment("Production", new Employee[] {
                new Employee(9, "Christian P. Laclair"),
                new Employee(10, "James L. Kelsey"),
                new Employee(11, "Howard M. Carpenter"),
                new Employee(12, "Jennifer T. Tapia"),
            }));
            departments.Add(new EmployeeDepartment("Finance", new Employee[] {
                new Employee(13, "Karen J. Kelly"),
                new Employee(14, "Judith P. Underhill"),
                new Employee(15, "Russell E. Belton"),
            }));
            return departments;
        }
    }


    public class Employee
    {
        public Employee(int id, string name)
        {
            ID = id;
            Name = name;
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }
    public class EmployeeDepartment
    {
        public string Name { get; set; }
        public ObservableCollection<Employee> Employees { get; }


        public EmployeeDepartment(string name, IEnumerable<Employee> employees)
        {
            Name = name;
            Employees = new ObservableCollection<Employee>(employees);
        }
    }


    [AddINotifyPropertyChangedInterface]
    public class TreeNode
    {
        //public int NodeID { get; set; }
        //public int ParentID { get; set; }
        public string NodeName { get; set; }
        public bool IsChecked { get; set; }
        public ObservableCollection<TreeNode> ChildNodes { get; set; }
        public TreeNode()
        {
            IsChecked = true;
            ChildNodes = new ObservableCollection<TreeNode>();
        }
    }
}

通过SetIsChecked方法实现了主节点取消勾选后,子节点也跟着去勾选,要勾选子节点,也先得选中主节点.

源码下载

  链接:https://pan.baidu.com/s/1ty500tUFPNGtfnJorqaZ7A 

提取码:6666

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值