关于用递归调用方法从数据库读取数据并绑定TreeView的问题
大家好,我在学用递归调用方法从数据库读取数据并绑定TreeView,数据库设计如下:
DID 商品类型编号
比如父节点书籍类101,服饰类102.
子节点小说书籍10101,教材书籍10102
侦探小说1010101,爱情小说1010102
JAVA教材1010201,C#教材1010202
等等
DName 商品类型名称
DUrl 商品地址
ParentID 父节点的ID,即DID,若没有父节点,为0
下面是程序中的部分代码,省略了些不重要的.页面中的TreeView对象ID是:TV
public partial class _Default : System.Web.UI.Page
{
//创建全局DataSet对象ds
DataSet ds;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.TV.Dispose();
//填充数据集
GetDataToDataSet();
//调用绑定TreeView的方法InitTreeView,
//传进2个参数分别是当前页面上TreeView(TV)的父节点
//和数据库中父节点列(ParentID)中代表没有父节点的"0"
InitTreeView(this.TV.Nodes, "0");
}
}
//绑定TreeView的方法
public void InitTreeView(TreeNodeCollection tnc, string parentId)
//需要两个参数,第一个的意思是TreeView节点的集合,即也可是父节点,也可是子节点
//第二个参数意思是数据库中父节点列(ParentID)的值
{
//创建DataSet的视图DataView,便于后续筛选
DataView dv= new DataView();
//声明一个TreeView节点
TreeNode tnNode;
//填充视图dv的数据为ds的List表
dv.Table = ds.Tables["List"];
//这句话的意思是,只看视图中列ParentID等于parentId的那些行
dv.RowFilter = "ParentID=" + parentId;
//开始遍历,类型是视图中的行,即DataRowView,即遍历视图中的每一行
foreach (DataRowView drv in dv)
{
//初始化节点
tnNode = new TreeNode();
//给节点的属性赋值
tnNode.Value = drv["DID"].ToString();
tnNode.Text = drv["DName"].ToString();
tnNode.NavigateUrl = drv["DUrl"].ToString();
//疑问:
//程序走完下面的Add方法后,是继续返回循环开始,不走下面的递归调用方法,
//还是继续走下面的递归调用方法,返回此方法的开始阶段,而不是继续遍历?
//也就是说,是先全部添加完父节点,再添加子节点,还是添加一个父节点,紧跟着添加此父节点的子节点呢?
//我感觉应该是后者,添加一个父节点,再把它的子节点添加上.
//那么问题又来了,方法第一次走的时候,参数tnc是个父节点,ID是从数据库读取的,比如101(书籍),我们添加上 了
//然后递归调用,tnc成了子节点,ID从数据库读取,比如10101(小说类),此时添加了书籍的第一个子节点
//然后继续递归调用,查询父类节点ID是10101(小说类)的节点,找到了侦探小说(1010101),此时添加了小说类的第一个子节点
//然后继续递归调用,此时传入的方法第二个参数是不是侦探小说的ID,即1010101?那么假如侦探小说类下面没有子节点了,方法遍历不到,下一步方法该怎么执行呢?
//或者,我的理解从一开始就是错误的?
tnc.Add(tnNode);
//递归调用方法,传入的第一个参数是一个子节点.
InitTreeView(tnNode.ChildNodes, tnNode.Value);
}
}
绑定DataSet的方法省略...
做完后虽然页面能正常显示,并加载了数据库中的节点,父子节点关系也正确,但由于是自学,所以有几个地方不明白,我在上面的注释中写出来了.麻烦大家指点一下,谢谢!
另外还请看看我自己写的注释有没有理解错了的,也请一并改正!
------解决方案--------------------
你可以按f5,再按f11,单步执行下,就理解了。
你这个是先添加根节点,再添加下一级。