在ASP.NET中使用递归函数实现树状视图控制

在开发Web应用程序时,经常需要以层次结构的形式展示数据。例如,展示一个家族的成员关系或分类信息。当数据的层次深度非常大时,如何有效地展示这些数据成为一个挑战。本文将介绍一种通用的解决方案,帮助开发者处理类似的业务需求。

业务需求

假设需要展示一个家族或分类的层次结构。在这种情况下,通过XML树或结构化数据库进行迭代变得复杂。解析数据是问题的一部分,而将其以图形视图的形式展示则是另一部分。

挑战在于数据结构不是硬编码的,任何时候都可能在运行时添加新的叶子节点或父节点。因此,使用XML结构会带来挑战,因为解析、定位父节点和更新XML数据会给程序员带来额外的负担。

解决方案

要遵循的方法:

  • 将数据结构化为所需的层次格式 - 数据表模式。
  • 建立解析逻辑。编写递归函数。
  • 将其绑定到树视图控件。

重要的贡献因素是创建良好的数据表结构并将其绑定到树视图控件。

技术:

数据库实现:

  • 创建表 tbl_Tree_Hierarchy
  • 创建存储过程 ssp_get_hierarchy:这将提供节点ID及其子信息以及它所属的叶子节点或分支的深度或级别。

以下是上述存储过程的结果集。在SQL Server 2005中使用公共表表达式(WITH Clause)引用递归数据集的最佳用法:

创建递归函数以遍历层次树数据结构。此功能是使用ASP.NET2.0开发的,可以使用CSharp .NET 3.5中的LINQ避免使用递归函数。使用匿名委托,可以比较集合对象与一些逻辑条件。一旦结果集被过滤,它就可以被遍历并可以作为对象项添加到树视图控件中。

创建一个包含Htree对象的泛型集合HierarchyTrees。

public class HierarchyTrees : List { public class HTree { private string m_NodeDescription; private int m_UnderParent; private int m_LevelDepth; private int m_NodeID; public int NodeID { get { return m_NodeID; } set { m_NodeID = value; } } public string NodeDescription { get { return m_NodeDescription; } set { m_NodeDescription = value; } } public int UnderParent { get { return m_UnderParent; } set { m_UnderParent = value; } } public int LevelDepth { get { return m_LevelDepth; } set { m_LevelDepth = value; } } } }

PopulateTreeview()函数将从数据库中获取记录集,并将泛型集合树填充。

private void PopulateTreeview() { this.tvHierarchyView.Nodes.Clear(); HierarchyTrees hierarchyTrees = new HierarchyTrees(); HierarchyTrees.HTree objHTree = null; using (SqlConnection connection = new SqlConnection( @" Persist Security Info=False;Integrated Security=SSPI; database=FamilyTree;server=[Local]" )) { connection.Open(); using (SqlCommand command = new SqlCommand( "SSP_GET_HIERARCHY", connection)) { command.CommandType = System.Data.CommandType.StoredProcedure; SqlDataReader reader = command.ExecuteReader (System.Data.CommandBehavior.CloseConnection); while (reader.Read()) { objHTree = new HierarchyTrees.HTree(); objHTree.LevelDepth = int.Parse(reader["LEVEL_DEPTH"].ToString()); objHTree.NodeID = int.Parse(reader["NODE_ID"].ToString()); objHTree.UnderParent = int.Parse(reader["UNDER_PARENT"].ToString()); objHTree.NodeDescription = reader["NODE_DESCRIPTION"].ToString(); hierarchyTrees.Add(objHTree); } } }

遍历集合。

foreach (HierarchyTrees.HTree hTree in hierarchyTrees) { HierarchyTrees.HTree parentNode = hierarchyTrees.Find ( delegate (HierarchyTrees.HTree emp) { return emp.NodeID == hTree.UnderParent; }); if (parentNode != null) { foreach (TreeNode tn in tvHierarchyView.Nodes) { if (tn.Value == parentNode.NodeID.ToString()) { tn.ChildNodes.Add(new TreeNode(hTree.NodeDescription.ToString(), hTree.NodeID.ToString())); } if (tn.ChildNodes.Count > 0) { foreach (TreeNode ctn in tn.ChildNodes) { RecursiveChild(ctn, parentNode.NodeID.ToString(), hTree); } } } } else { tvHierarchyView.Nodes.Add(new TreeNode(hTree.NodeDescription, hTree.NodeID.ToString())); } } tvHierarchyView.ExpandAll(); }

创建递归函数以遍历层次树数据结构。此功能是使用ASP.NET2.0开发的,可以使用CSharp .NET 3.5中的LINQ避免使用递归函数。使用匿名委托,可以比较集合对象与一些逻辑条件。一旦结果集被过滤,它就可以被遍历并可以作为对象项添加到树视图控件中。创建一个包含Htree对象的泛型集合HierarchyTrees。

public void RecursiveChild(TreeNode tn, string searchValue, HierarchyTrees.HTree hTree) { if (tn.Value == searchValue) { tn.ChildNodes.Add(new TreeNode(hTree.NodeDescription.ToString(), hTree.NodeID.ToString())); } if (tn.ChildNodes.Count > 0) { foreach (TreeNode ctn in tn.ChildNodes) { RecursiveChild(ctn, searchValue, hTree); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485