C# WPF TreeView用法实例解析

概述

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

结果演示:.

C# WPF TreeView用法实例解析

代码讲解

    前台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