第一种:
/// <summary>
/// 页面加载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
//加载页面时,动态读取国家列表到DropList
CreateTree();
}
/// <summary>
/// 绑定生成一个有树结构的下拉菜单
/// </summary>
/// <param name="dtNodeSets">菜单记录数据所在的表</param>
/// <param name="strParentColumn">表中用于标记父记录的字段</param>
/// <param name="strRootValue">第一层记录的父记录值(通常设计为0或者-1或者Null)用来表示没有父记录</param>
/// <param name="strIndexColumn">索引字段,也就是放在DropDownList的Value里面的字段</param>
/// <param name="strTextColumn">显示文本字段,也就是放在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)
{
TreeNode tnNode = new TreeNode();
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--;
}
/// <summary>
/// SQL语句查询,再绑定到DropList里面
/// </summary>
private void CreateTree()
{
//查询ZoneList
string sql = "SELECT *FROM Zone";
DataTable dt= DataAccess.GetDataSet(sql);
MakeTree(dt, "parentid", "0", "zone_id", "zonename_en", zone_id, -1);
}
例如:
表结构
-----
id(编号) name(名称) parentid(父类ID)
1 一级目录1 0
2 一级目录2 0
3 一级目录3 0
4 二级目录1 1
5 二级目录2 1
6 二级目录3 1
7 二级目录4 2
在下拉列表框里显示的结果如下
------ 对应的values值(id值)
├一级目录1 1
├二级目录1 4
├二级目录2 5
├二级目录3 6
├一级目录2 2
├二级目录4 7
├一级目录3 3
------------------------
利用递归算法来实现:
/// <summary>
/// 绑定生成一个有树结构的下拉菜单
/// </summary>
/// <param name="dtNodeSets">菜单记录数据所在的表</param>
/// <param name="strParentColumn">表中用于标记父记录的字段</param>
/// <param name="strRootValue">第一层记录的父记录值(通常设计为0或者-1或者Null)用来表示没有父记录</param>
/// <param name="strIndexColumn">索引字段,也就是放在DropDownList的Value里面的字段</param>
/// <param name="strTextColumn">显示文本字段,也就是放在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 (j = 0; j < i; j++)
strPading += " ";//如果要增加缩入的长度,改成两个全角的空格就可以了
foreach (DataRowView drv in dvNodeSets)
{
TreeNode tnNode = new TreeNode();
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--;
}
经过多次调试,总算应了“功夫不负有心人”这句话,最终调试成功,下面是我的调用语句供大家参考:
private void CreateTree() {
string sqlStr = "Select id,parent_id,name From sc_memcat order by position desc";
DataTable dt = DBFun.dataTable(sqlStr);
MakeTree(dt, "parent_id", "0", "id", "name", memcat_id, -1);
}
CreateTree(); //调用生成一个有树结构的下拉菜单的函数
第二种:
NodeCategory.GetSubCategory方法是根据ParentId获取该节点下的列表。简单的说就是绑定下拉框
//用来存放每次递归循环的结果
private readonly List<NodeCategory> _NodeCategoryList = new List<NodeCategory>();
List<NodeCategory> list = NodeCategory.GetSubCategory("0");
//第一次加载时调用方法传参
CreateTree(null, list);
ParentId.DataSource = _NodeCategoryList;
ParentId.DataTextField = "C_NAME";
ParentId.DataValueField = "C_ID";
ParentId.DataBind();
public void CreateTree(NodeCategory parentCategory, List<NodeCategory> list)
{
StringBuilder sb = new StringBuilder();
int parentCount = 0;
//用foreach遍历dv
foreach (NodeCategory category in list)
{
parentCount = Convert.ToInt32(category.PARENTS_COUNT);
for (int i = 0; i < parentCount; i++)
{
sb.Append(" ");
if (i == parentCount - 1)
{
sb.Append("└─ ");
}
}
category.C_NAME = sb + category.C_NAME;
sb.Clear();
_NodeCategoryList.Add(category);
//递归调用方法本身
List<NodeCategory> subList = NodeCategory.GetSubCategory(category.C_ID);
CreateTree(category, subList);
}
}