XAML前端代码:
<Window x:Class="Treeview.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Treeview"
Title="MainWindow" Height="350" Width="525">
<TreeView x:Name="treeView" Width="270" MaxHeight="520" BorderThickness="0">
<TreeView.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal" x:Name="stankPanel">
<CheckBox x:Name="checkBox" IsChecked="{Binding IsCheck}" Tag="{Binding Id}" Click="CheckBox_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image Source="{Binding Icon}" Height="20" Width="20" Margin="5"/>
<TextBlock Text="{Binding Title}" FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
TreeCategory【实现INotifyPropertyChanged接口】:
public class TreeCategory : INotifyPropertyChanged
{
private int id;
private string title;
private bool isCheck;
private int parentID;
private ObservableCollection<TreeCategory> children;
private string icon;
/// <summary>
/// 节点编号
/// </summary>
public int Id { get { return id; } set { id = value; OnPropertyChanged("Id"); } }
/// <summary>
/// 名称
/// </summary>
public string Title { get { return title; } set { title = value; OnPropertyChanged("Title"); } }
/// <summary>
/// 是否选中
/// </summary>
public bool IsCheck { get { return isCheck; } set { isCheck = value; OnPropertyChanged("IsCheck"); } }
/// <summary>
///父节点
/// </summary>
public int ParentID { get { return parentID; } set { parentID = value; OnPropertyChanged("ParentID"); } }
/// <summary>
/// 子节点
/// </summary>
public ObservableCollection<TreeCategory> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<TreeCategory>();
}
return children;
}
set
{
if (children == null)
{
children = new ObservableCollection<TreeCategory>();
}
children = value; OnPropertyChanged("Children");
}
}
/// <summary>
/// 图标
/// </summary>
public string Icon { get { return icon; } set { icon = value; OnPropertyChanged("Icon"); } }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
后台代码:
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<TreeCategory> obList=new ObservableCollection<TreeCategory> ();
public MainWindow()
{
InitializeComponent();
this.treeView.ItemsSource = InitData();
}
/// <summary>
/// 数据初始化
/// </summary>
/// <returns></returns>
private ObservableCollection<TreeCategory> InitData()
{
ObservableCollection<TreeCategory> tcList = new ObservableCollection<TreeCategory>() {
new TreeCategory(){Id = 1,Title = "Node1.",ParentID = 0},
new TreeCategory(){Id = 2,Title = "Node2.",ParentID = 0},
new TreeCategory(){Id = 3,Title = "Node3.",ParentID = 1},
new TreeCategory(){Id = 4,Title = "Node4.",ParentID = 3},
new TreeCategory(){Id = 5,Title = "Node5.",ParentID = 3},
new TreeCategory(){Id = 6,Title = "Node6.",ParentID = 4},
new TreeCategory(){Id = 7,Title = "Node7.",ParentID = 2},
new TreeCategory(){Id = 8,Title = "Node8.",ParentID = 2},
new TreeCategory(){Id = 9,Title = "Node9.",ParentID = 8},
};
//最开始的父节点默认为0,如果不递归,TreeView并不会生成【树】
obList = FindChild(tcList, 0);
return obList;
}
/// <summary>
/// 遍历子类
/// </summary>
/// <param name="tcList"></param>
/// <param name="id">父类编号</param>
/// <returns></returns>
private ObservableCollection<TreeCategory> FindChild(ObservableCollection<TreeCategory> tcList,int id)
{
ObservableCollection<TreeCategory> childList = new ObservableCollection<TreeCategory>();
foreach (var item in tcList)
{
if (item.ParentID == id)
{
childList.Add(item);
//判断是否有子节点
int count = tcList.Where(a => a.ParentID == item.Id).Count();
if (count > 0)
{
item.Children = FindChild(tcList, item.Id);
}
}
}
return childList;
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
int id =Convert.ToInt32(checkBox.Tag);
//寻找被点击的checkbox
TreeCategory trees = FindNode(this.treeView.Items.Cast<TreeCategory>().ToList(), id);
//如果有子类,则子类状态和被点击的CheckBox状态一致
if (trees.Children.Count()>0)
{
IsCheckBoxed(trees.Children, Convert.ToBoolean(checkBox.IsChecked));
}
}
/// <summary>
/// 寻找被点击的CheckBox
/// </summary>
/// <param name="Nodes"></param>
/// <param name="id">需要寻找的ID</param>
/// <returns></returns>
private TreeCategory FindNode(List<TreeCategory> Nodes, int id)
{
TreeCategory tree = new TreeCategory();
foreach (var item in Nodes)
{
if (item.Id!= id)
{
tree= FindNode(item.Children.ToList(), id);
}
else
{
tree = item;
}
if (tree.Id==id)
{
return tree;
}
}
return tree;
}
/// <summary>
/// 更改子节点状态
/// </summary>
/// <param name="tcList">子节点集合</param>
/// <param name="flag">true?flag</param>
private void IsCheckBoxed(ObservableCollection<TreeCategory> tcList,bool flag)
{
foreach (var item in tcList)
{
item.IsCheck = flag;
if (item.Children.Count() > 0)
{
IsCheckBoxed(item.Children, flag);
}
}
}
}
要想子父节点联动,需要使用递归。
效果图:
下载链接:
百度网盘链接:https://pan.baidu.com/s/1W_HUG4qDzAOFIhsL6wUT1Q 提取码:3ogu
CSDN链接: https://download.csdn.net/download/dear200892/11827351