无限树状结构逻辑
l 应用场景特点
1)列表(Datable)
编号 |
名称 |
父编号 |
ID |
Name |
ParentID |
2)仅有一个根节点,每个节点有且只有一个父节点。
典型的递归算法:
Ø 递归入口:仅有一个根节点(根节点编号)。
Ø 递归循环体:每个节点有且只有一个父节点,子节点是上级节点的子节点,又是下级节点的父节点。(孙又有子,子又有孙,子子孙孙无穷尽)
Ø 循环出口:不再有子节点。
子节点编号与父节点编号不能相同,不能交叉。
函数
/// <summary>
/// 绑定生成一个有树结构的下拉菜单
/// </summary>
/// <param name="dtNodeSets"> Datable记录数据所在的表</param>
/// <param name="strParentColumn"> ParentID表中用于标记父记录的字段</param>
/// <param name="strRootValue">根节点ID第一层记录的父记录值(通常设计为0或者-1或者Null)用来表示没有父记录</param>
/// <param name="strIndexColumn">ID索引字段,也就是放在DropDownList的Value里面的字段</param>
/// <param name="strTextColumn">Name显示文本字段,也就是放在DropDownList的Text里面的字段</param>
/// <param name="drpBind">需要绑定的DropDownList</param>
/// <param name="i">用来控制缩入量的值,请输入-1</param>
private void makeTree(DataTable dtNodeSets, string strParentColumn, string strRootValue, string strIndexColumn, string strTextColumn, DropDownList drpBind, int i)
{
//每向下一层,多一个缩入单位
i++;
DataView dvNodeSets = new DataView(dtNodeSets);
dvNodeSets.RowFilter = strParentColumn + "=" + strRootValue;
string strPading = ""; //缩入字符
//通过i来控制缩入字符的长度,我这里设定的是一个全角的空格
for (int j = 0; j < i; j++)
strPading += " ";//如果要增加缩入的长度,改成两个全角的空格就可以了
foreach (DataRowView drv in dvNodeSets)
{
ListItem li = new ListItem(strPading + "┣" + drv[strTextColumn].ToString(), drv[strIndexColumn].ToString());
drpBind.Items.Add(li);
makeTree(dtNodeSets, strParentColumn, drv[strIndexColumn].ToString(), strIndexColumn, strTextColumn, drpBind, i);
}
//递归结束,要回到上一层,所以缩入量减少一个单位
i--;
}
调用方法:
string sql = "Select JGDM,JGMC,SJJG from [C_SUBCOMPANY] order by JGDM ";
System.Data.DataTable dt = SFS.Data.SqlServer.GetSingleData.GetOnlyOneDataTable(sql);
makeTree(dt, "SJJG", "000000", "JGDM", "JGMC", drp, -1);