在編程中很可能使用到多級動態目錄,如果使用一般的方法將多級目錄綁定到Treeview就顯得非常局促了,所以,最好的辦法就是使用遞歸,使用遞歸就完全不用去考慮目錄的層次有多深.代碼其實很簡單. View Code 1 protected void Page_Load(object sender, Ev ...
在編程中很可能使用到多級動態目錄,如果使用一般的方法將多級目錄綁定到Treeview就顯得非常局促了,所以,最好的辦法就是使用遞歸,使用遞歸就完全不用去考慮目錄的層次有多深.
代碼其實很簡單.
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 string connstring = "Data Source=.;Initial Catalog=MyDB;Persist Security Info=True;User ID=sa;Password=******"; 4 SqlConnection con = new SqlConnection(connstring); 5 SqlDataAdapter sda = new SqlDataAdapter( "select ID,ParentID,Name from Sys_Directory where isuse=1",con); 6 DataSet ds = new DataSet(); 7 sda.Fill(ds); 8 DataTable dt = ds.Tables[0]; 9 BindTree(dt,null,0); 10 } 11 private void BindTree(DataTable dt, TreeNode parentnode, int parentid) 12 { 13 14 DataRow[] rows = dt.Select(string.Format("ParentID={0}", parentid)); 15 foreach (DataRow row in rows) 16 { 17 TreeNode node = new TreeNode(); 18 node.Text = row["Name"].ToString(); 19 node.Value = row["ID"].ToString(); 20 BindTree(dt, node,Convert.ToInt32( row["ID"])); 21 if (parentnode == null) 22 { 23 tv1.Nodes.Add(node); 24 } 25 else 26 { 27 parentnode.ChildNodes.Add(node); 28 } 29 } 30 31 }
在遞歸方法中,傳遞一個我們從資料庫中查詢出來的datatable數據源,一個TreeNode,以及目錄的父級ID.
下麵這句話可能有些人不理解,dt.Select是系統的方法,按照主鍵順序匹配每一條數據.這裡的主鍵並非資料庫中的主鍵,而是後面括弧中的指定的主鍵.
string.Format是格式化字元串
DataRow[] rows = dt.Select(string.Format("ParentID={0}", parentid));
後面的代碼就是開始迴圈並遞歸了.
遞歸演算法有這樣第一特點,就是先迴圈遍歷的終點,然後從終點開始遞歸計算.
在將目錄綁定到treeview的時候進行一個判斷,判斷此節點是否為根節點.
但是,如果這個時候你在if處打上斷點,然後F11,會發現,我們開始給parentnode復的null值,這時候判斷卻不是為空的,這是為什麼呢?難道給Treenode賦null與parentnode=null不一樣?還是遞歸演算法不是迴圈到終點在從終點遞歸?其實不然.
if (parentnode == null)
{
tv1.Nodes.Add(node);
}
else
{
parentnode.ChildNodes.Add(node);
}
我們回過去看if上面的代碼,BindTree(dt, node,Convert.ToInt32( row["ID"]));
在調用自身方法的時候是需要傳遞一個parentnode參數的,而這個node已經在迴圈的時候已經賦值了,在開始遞歸的時候這個node的值不是開始的null值,而是你目錄的最後一個子節點.
所以,遞歸開始從最後子節點開始的.最終遞歸到根節點.