【转载】WPF中TreeView控件数据绑定和后台动态添加数据(一)

news/发布时间2024/5/16 14:08:01

原文链接:https://www.cnblogs.com/larissa-0464/p/10227483.html

数据绑定:

更新内容:补充在MVVM模式上的TreeView控件数据绑定的代码。

xaml代码:

复制代码
<TreeView Name="syntaxTree" ItemsSource="{Binding TreeNodes}"><TreeView.ItemTemplate><HierarchicalDataTemplate DataType="{x:Type local:TreeNode}" ItemsSource="{Binding Path=ChildNodes}"><TextBlock Text="{Binding NodeName}"/></HierarchicalDataTemplate></TreeView.ItemTemplate>
</TreeView>
复制代码

TreeView中的ItemsSource绑定的是一个名为TreeNodes的TreeNode的列表,即List<TreeNode>TreeNodes。HierarchicalDataTemplate中的ItemsSource绑定的TreeNodes中的每个节点的ChildNodes属性。

ViewModel.cs中的代码(有删减):

复制代码
public class ViewModel : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;private List<TreeNode> treenodes = new List<TreeNode>();public List<TreeNode> TreeNodes{get { return treenodes; }set{treenodes = value;if (PropertyChanged != null)PropertyChanged(this, new PropertyChangedEventArgs("TreeNodes"));}}public ViewModel(){// Nodes是我已经获得的一组节点TreeNodes = getChildNodes(0,Nodes);}private List<TreeNode> getChildNodes(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 = getChildNodes(node.NodeID, otherNodes);return mainNodes;}
}
复制代码

使用MVVM模式,那么xaml.cs文件就会变得非常简单了,基本只有一句代码了:

this.DataContext = new ViewModel();

该模式的好处就是使得UI设计和后端代码分开,只通过数据绑定进行连接。尝试用了几次,真的还蛮方便。


 

TreeView数据绑定需要使用层次结构数据模板(HierarchicalDataTemplate)来显示分层数据。XAML代码如下:

复制代码
<TreeView Name="chapterTree" Grid.Column="0"><TreeView.ItemTemplate><HierarchicalDataTemplate ItemsSource="{Binding Path=ChildNodes}"><StackPanel><Label Content="{Binding Path=NodeName}"/></StackPanel></HierarchicalDataTemplate></TreeView.ItemTemplate></TreeView>
复制代码

其中,ItemsSource绑定的对象ChildNodes应该是一个集合类型:List<TreeNode>,Label中绑定的是TreeNode的NodeName属性,TreeNode类定义如下所示:

复制代码
public class TreeNode{public int NodeID { get; set; }public int ParentID { get; set; }public string NodeName { get; set; }public List<TreeNode> ChildNodes { get; set; }public TreeNode(){ChildNodes = new List<TreeNode>();}}
复制代码

因为是树形结构,因此TreeNode需要有NodeID属性和ParentID属性,即某个树节点node本身的ID和它所属的父节点的ID。以目录为例,则xaml.cs中的代码如下。首先是写入了数据,在我实际项目中,这些数据是从DB中查询的,这里为了简化,直接Input数据了。

复制代码
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();InputData();chapterTree.ItemsSource = getNodes(0, nodes);}private List<TreeNode> nodes;private void InputData(){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"}};}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;}}
复制代码

需要注意的就是NodeID是不断增加的,每个节点都有自己的ID,而其ParentID就看它是属于哪个父节点的了。getNodes()是一个递归方法,就是不断读取某个节点的子节点。运行结果如图所示:

 

后台动态添加TreeView:

一开始,没用数据绑定,就直接在xaml.cs中使用treeview,虽然后来用了数据绑定之后发现还是绑定更方便,但是这种在后台构建treeview的方法没准哪天也能用到,就记录一下吧。

XAML文件,使用一个TreeView控件

复制代码
<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="60*"/><ColumnDefinition Width="100*"/></Grid.ColumnDefinitions><TreeView Name="chapterTree" Grid.Column="0"/></Grid>
复制代码

XAML.CS文件,同样使用递归方法,就是不断的新建treeviewitem控件。

复制代码
public partial class DynamicTreeView : Window{public DynamicTreeView(){InitializeComponent();InputData();ShowTreeView();}private List<TreeNode> nodes;private void InputData(){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"}};}private void ShowTreeView(){TreeViewItem tv1 = new TreeViewItem();chapterTree.Items.Add(tv1);GetNodes(0, tv1);}private void GetNodes(int parentID, TreeViewItem tv){List<TreeNode> mainNodes = nodes.Where(x => x.ParentID == parentID).ToList();foreach(var item in mainNodes){TreeViewItem tv1 = new TreeViewItem();tv1.Header = item.NodeName;tv.Items.Add(tv1);GetNodes(item.NodeID, tv1);}}}
复制代码

运行图:总归是没有databinding方便。刚开始学习WPF,一开始没想过要用数据绑定,总感觉只要能实现自己想要的东西就可以了,不用管实现过程,后来使用了之后发现,使用数据绑定构建MVVM架构的应用还是挺好的。

 第二部分将总结给节点添加事件的方法。

https://www.cnblogs.com/larissa-0464/p/12441607.html

关于TreeView控件的demo:

WPF中常用控件(TreeView, ComboBox, DataGrid, ListView)使用MVVM模式绑定的demo - 南风小斯 - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/52424338.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

实验二。

include <stdio.h> include<stdlib.h> include<time.h> define N 5 int main() { int number; int i; srand(time(0));for(i=0;i<N;++i){ number=rand()%65+1; printf("20238331%04d\n",number); } return 0;}问题一:一到六十五之间随…

httprunner 4.x学习 - 05校验(validate)

前言 HttpRunner4.x 内置了丰富的校验结果的方式 校验方式assert缩写说明equal "eq", "equals", "equal" 相等less_than "lt", "less_than" 小于less_or_equals "le", "less_or_equals" 小于或等于grea…

继续MDT的bug,

简介 这个据说是多播的bug 如果你真的想使用多重广播,这是我如何解决这个问题的。获取 Windows 11 ISO (x64) 挂载 ISO,在 sources 文件夹中,您需要 2 个文件wdscommon.dll和imagelib.dll 将这些文件复制到 x64 文件夹> mdt 部署共享>工具(例如,在我的文件夹中,…

建设库数据爬取

1. python部分: # -*- coding:utf-8 -*-# @Time : 2024/4/14 17:57 # @Author : 快乐的小猴子 # @Version : # @Function : import requests import json import subprocess from functools import partial # 专门用来固定参数的 subprocess.Popen = partial(subprocess.Po…

[ABC349] AtCoder Beginner Contest 349 题解

最近AT怎么这么寄[ABC349] AtCoder Beginner Contest 349 题解 目录[ABC349] AtCoder Beginner Contest 349 题解A - Zero Sum GameB - CommencementC - Airport CodeD - Divide IntervalE - Weighted Tic-Tac-ToeF - Subsequence LCMG - Palindrome Construction总结 A - Zero…

拆分内容

问题:将以下在一个单元格中的内容按品名、数量、单价、金额拆分出来函数公式解决:B2公式 =LEFT(TEXTBEFORE(A2,""),LEN(TEXTBEFORE(A2,""))-LEN(C2)) C2公式 =-LOOKUP(1,-RIGHT(TEXTBEFORE(A2,""),SEQUENCE(99))) D2公式 =-LOOKUP(1,-LEFT(TEX…