在开发Web应用程序时,经常需要以层次结构的形式展示数据。例如,展示一个家族的成员关系或分类信息。当数据的层次深度非常大时,如何有效地展示这些数据成为一个挑战。本文将介绍一种通用的解决方案,帮助开发者处理类似的业务需求。
假设需要展示一个家族或分类的层次结构。在这种情况下,通过XML树或结构化数据库进行迭代变得复杂。解析数据是问题的一部分,而将其以图形视图的形式展示则是另一部分。
挑战在于数据结构不是硬编码的,任何时候都可能在运行时添加新的叶子节点或父节点。因此,使用XML结构会带来挑战,因为解析、定位父节点和更新XML数据会给程序员带来额外的负担。
要遵循的方法:
重要的贡献因素是创建良好的数据表结构并将其绑定到树视图控件。
技术:
数据库实现:
以下是上述存储过程的结果集。在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);
}
}
}