概述
TreeView是常用的树状列表,在项目开发中也时常会用到,这节主要讲解treeview在wpf的基本用法!
结果演示:.
代码讲解
前台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