博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
wpf数据自动树结构
阅读量:5099 次
发布时间:2019-06-13

本文共 6935 字,大约阅读时间需要 23 分钟。

  在项目中,时常会遇到存在上下级关系的数据。在呈现方面,按照传统方法,不得不组装TreeNode之后添加到TreeView 中,已实现树形数据的显示。如果项目中需要多处使用树,毫无疑问这将存在巨大的代码冗余,会有无数针对不同实体组件TreeNode的代码出现,整体风格糟糕至极。

  在近期的项目中,很多地方拥有这样的上下级关系,如下图所示,可以清楚的看出它们直接的关系

  在数据的查询上,一般对于Oracle不太熟悉的人,可能就会采用 in或者exist关键字来进行筛选, 实际上Oracle有已经有递归查询的语法存在,对于Oracle不太熟悉的看官,可以百度一下。

这里列出了示例:

select t.project_id,t.project_name,t.p_project_id,t.p_project_name,t.category from sys_project_info s start with s.category in (10,11,21) connect by prior s.project_id=s.p_project_id and s.project_name = s.p_project_name;

  

  到这里数据的提取部分就已经完成,剩下的就是树形数据的组建过程,也就是数据的呈现。归根结底还是递归,在这里只是对递归过程进行了封装,可以直接移植到WPF或者Silverlight项目中,代码如下:

1 using Microsoft.Practices.Prism.ViewModel;  2 using System;  3 using System.Collections;  4 using System.Collections.Generic;  5 using System.Collections.ObjectModel;  6 using System.Linq;  7 using System.Runtime.Serialization;  8 using System.Text;  9  10 namespace SysManager.Utility 11 { 12     public class TreeNode
: NotificationObject where T : BaseEntity 13 { 14 private T _parentNode; 15 private T _currentNode; 16 private bool _isChecked; 17 private bool _canChecked; 18 19 ///
20 /// 父节点 21 /// 22 public dynamic Key { get; set; } 23 24 ///
25 /// 子节点 26 /// 27 public ObservableCollection
> ChildrenNodes { get; set; } 28 29 ///
30 /// 是否允许被选中 31 /// 32 public bool CanChecked 33 { 34 get { return _canChecked; } 35 set 36 { 37 if (_canChecked == value) 38 return; 39 _canChecked = value; 40 RaisePropertyChanged("CanChecked"); 41 } 42 } 43 44 ///
45 /// 是否处于被选中状态 46 /// 47 public bool IsChecked 48 { 49 get { return _isChecked; } 50 set 51 { 52 if (_isChecked == value) 53 return; 54 _isChecked = value; 55 RaisePropertyChanged("IsChecked"); 56 } 57 } 58 ///
59 /// 当前选中节点 60 /// 61 public T CurrentNode 62 { 63 get { return _currentNode; } 64 set 65 { 66 if (_currentNode == value) 67 return; 68 _currentNode = value; 69 RaisePropertyChanged("CurrentNode"); 70 } 71 } 72 ///
73 /// 当前节点的父级节点 74 /// 75 public T ParentNode 76 { 77 get { return _parentNode; } 78 set 79 { 80 if (_parentNode == value) 81 return; 82 _parentNode = value; 83 RaisePropertyChanged("ParentNode"); 84 } 85 } 86 87 public TreeNode() 88 { 89 this.CanChecked = true; 90 } 91 92 static TreeNode
staticNode; 93 94 ///
95 /// 将数据组织成一个拥有上下级管理的树形结构数据集合 96 /// 97 ///
主键的数据类型
98 ///
执行过GroupBy语句的数据源 99 ///
结果数据100 ///
子节点标识字段名称101 ///
父节点标识字段名称102 ///
103 ///
已生成的树形结构实体
104 public TreeNode
GenerateTreeNodes
(IEnumerable
> nodeSource, TreeNode
resultTreeNode, string keyName, string parentKeyName)105 {106 var orderedSource = nodeSource.OrderBy(groupList => groupList.Key);107 foreach (IGrouping
item in orderedSource)108 {109 var listChildrenNode = new ObservableCollection
>();110 object propertyParentValue = null;111 112 foreach (var child in item)113 {114 //get children id 115 object propertyValue = GetCurrentItemPropertyValue(keyName, child);116 //get parent id 117 if (propertyParentValue == null)118 propertyParentValue = GetCurrentItemPropertyValue(parentKeyName, child);119 120 if (propertyValue != propertyParentValue)121 {122 T parentNodeInstance = null;123 if (propertyParentValue != null)124 {125 var nodeParent = nodeSource.Where(x => x.Key.ToString() == propertyParentValue.ToString()).FirstOrDefault();126 if (nodeParent != null)127 parentNodeInstance = nodeParent.FirstOrDefault();128 }129 var node = new TreeNode
() { CurrentNode = child, Key = propertyValue, ChildrenNodes = new ObservableCollection
>(), ParentNode = parentNodeInstance };130 listChildrenNode.Add(node);131 }132 133 }134 135 TreeNode
parentNode = null;136 foreach (var root in listChildrenNode)137 {138 staticNode = null;139 parentNode = FindParentNode(resultTreeNode, item.Key);140 if (parentNode != null)141 break;142 }143 if (parentNode != null)144 {145 parentNode.ChildrenNodes = listChildrenNode;146 }147 else148 listChildrenNode.ToList().ForEach(childNode => resultTreeNode.ChildrenNodes.Add(childNode));149 150 }151 return resultTreeNode;152 }153 154 ///
155 /// 将一个拥有上下级关系的Tree转换为列表156 /// 157 public IEnumerable TreeNode2LinkedList { get; private set; }158 ///
159 /// 将treenode转换为列表160 /// 161 ///
162 ///
163 public void TreeNodeToLinkedList(TreeNode
originalSource)164 {165 if (originalSource != null && originalSource.ChildrenNodes != null)166 {167 if (originalSource.CurrentNode != null)168 {169 if (TreeNode2LinkedList == null)170 TreeNode2LinkedList = new List
();171 (TreeNode2LinkedList as List
).Add(originalSource.CurrentNode);172 }173 foreach (var item in originalSource.ChildrenNodes)174 {175 TreeNodeToLinkedList(item);176 }177 }178 }179 180 private static object GetCurrentItemPropertyValue(string keyName, T child)181 {182 var property = child.GetType().GetProperties().Where(prop => prop.Name == keyName).FirstOrDefault();183 object propertyValue = null;184 if (property != null)185 propertyValue = property.GetValue(child, null);186 return propertyValue;187 }188 189 ///
190 /// 寻找当前节点的父级节点191 /// 192 ///
当前节点193 ///
节点的Key194 ///
父级节点
195 private TreeNode
FindParentNode(TreeNode
rootNode, dynamic key)196 {197 198 if (rootNode.ChildrenNodes == null)199 return rootNode;200 foreach (var children in rootNode.ChildrenNodes)201 {202 if (children.Key == key)203 {204 staticNode = children;205 break;206 }207 else208 if (staticNode == null)209 FindParentNode(children, key);210 }211 if (rootNode.Key != null && (int)rootNode.Key == key)212 return rootNode;213 214 return staticNode;215 216 }217 }218 }
View Code

  

//调用方法var treeNode = new TreeNode
(); treeNode.GenerateTreeNodes
(result.OfType
().GroupBy(proj => proj.ParentProjectId), treeNode, "ProjectId", "ParentProjectId");

 

转载于:https://www.cnblogs.com/zeoy/p/3685262.html

你可能感兴趣的文章
MySQL索引背后的数据结构及算法原理
查看>>
#Leetcode# 209. Minimum Size Subarray Sum
查看>>
SDN第四次作业
查看>>
DM8168 DVRRDK软件框架研究
查看>>
django迁移数据库错误
查看>>
yii 跳转页面
查看>>
洛谷 1449——后缀表达式(线性数据结构)
查看>>
[最小割][Kruskal] Luogu P5039 最小生成树
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
(转)Android之发送短信的两种方式
查看>>
python第九天课程:遇到了金角大王
查看>>
字符串处理
查看>>
ECharts(Enterprise Charts 商业产品图表库)初识
查看>>
LeetCode Factorial Trailing Zeroes (阶乘后缀零)
查看>>
hdu 5402 Travelling Salesman Problem (技巧,未写完)
查看>>
[AIR] 获取U盘,打开U盘
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>