无限级树的填充方法
摘要:本文介绍将存储在数据库中的树型数据结构通过DataSet填充到TreeView的方法,并给出填充的函数实现。
TreeView是ASP.NET中常用的控件之一,常用的如部门、人员的显示。图1为一个部门、人员显示的界面,图中我将部门中的敏感数据抹掉了。
该应用采用了框架方式,左边框架包含的aspx页显示部门,点击某个部门后,该部门的所有人员显示到右面的页面中。
本例采用的部门树结构为Departments(DepartID, DepartName, SerialNum, ParentID)。其中DepartID为部门ID,自动增长;DepartName为部门名;ParentID为父结点ID;SerialNum为内部序号,即ParentID相同的部门的内部排序序号。
根结点可以用ParentID为null或-1表示,如果建立外键约束(ParentID参照DepartID取值),则ParentID只能取空值或DepartID中存在的值,这样我们用null表示根结点。
树控件填充后,还需要在点击某个结点时将该结点的DepartID的值传递到右面界面,以便显示该部门用户。
下面的函数采用递归方式填充树控件,参数的意义参考注释的内容。如果只需要填充,不需要导航,则可以取得tn.NavigateUrl和tn.Target赋值那两句,并去掉该函数最后两个参数。如果还有其它需要,请自行修改。
///
/// 填充树控件
///
/// 树控件结构所在表
/// 节点集合,调用时可以将TreeView1.Nodes传递进来
/// 根节点值,如果ParentID用null表示根结点,传递null
/// 父节点字段名,本例中为”ParentID”
/// 排序字段名,本例中为”SerialNum”
/// 显示的字段名,本例中为”DepartName”
/// 值字段名,也是传递到右边页面的值,为”DepartID”
/// 右边框架中显示的页Url
/// 右边框架的id
public void FillTree(DataTable dt, TreeNodeCollection tns, string strParentID, string strParentField, string strSortField, string strTextField, string strValueField, string strNavigate, string strTarget)
{
TreeNode tn = null;
DataRow[] drs;
if (strParentID == null)
drs = dt.Select(string.Format("{0} is null", strParentField), strSortField);
else
drs = dt.Select(string.Format("{0}={1}", strParentField, strParentID), strSortField);
foreach (DataRow dr in drs)
{
tn = new TreeNode();
tn.Text = dr[strTextField].ToString();
tn.Value = dr[strValueField].ToString();
tn.NavigateUrl = string.Format("{0}?P={1}", strNavigate, dr[strValueField]);
tn.Target = strTarget;
tn.SelectAction = TreeNodeSelectAction.SelectExpand;
tns.Add(tn);
FillTree(dt, tn.ChildNodes, dr[strValueField].ToString(), strParentField, strSortField, strTextField, strValueField, strNavigate, strTarget);
}
}
该段代码中,将新建的结点的SelectAction属性设置为SelectExpand,这样点击一个结点后,会选中该结点,并自动展开。
同时设置了NavigateUrl和Target属性,点击结点后会自动在Target框架中显示NavigateUrl页面。且该页面后有参数?P=x,这样可以在右边页面中用Request[“P”]取得传递进来的DepartID。
假设TreeView控件ID为tvDeparts。数据集为类型化数据集DepartSet,部门信息存放在Departments表中。显示用户的页面为Users.aspx,框架ID为Content。ParentID字段用null表示根结点。
调用代码如下:
// 填充数据集
DepartSet ds = new DepartSet();
DepartSetTableAdapters.DepartmentsTableAdapter adp = new DepartSetTableAdapters.DepartmentsTableAdapter();
adp.Fill(ds.Departments);
// 填充树
tvDeparts.Nodes.Clear();
FillTree(ds.Departments, tvDeparts.Nodes, null, "ParentID", "SerialNum", "DepartName", "DepartID", "Users.aspx", "Content");