有多种途径,如果是数据库读出,建议使用DataSet,或者可以使typed DataSet,递归的算法很简单(深度优先),也可以采用xml, xslt(转换成目录树层次结构)。以上两种方法,本人以为都比用Dictionary效率高。因为使用Dictionary你需要多次转储数据,而且还无法直接绑定数据。

解决方案 »

  1.   

    使用treeview控件,运用递归算法,很容易实现.
      

  2.   

    你的表结构基本上是正确的,不过再加几个字段看看!
    T_TreeInfo表名
    Item_id 主键
    Item_pid 父目录id
    Item_name目录名
    Item_child子目录数
    Item_layer层次数
    Item_order顺序
    link_page 链接页面
    sqlString="SELECT * FROM T_TreeInfo ORDER BY Item_order"
    然后生成dt
    for each dr in dt.rows
      在这里面要判断:
      layer用来在前面加一个空格,以形成缩近结构,用for循环实现;
      child用来判断没有子目录,用那么展开合扰图片,否则用其它图片
    用session("")保存目录的展开合扰状态,合扰时子目录不会显示;
     
    next
    还是不清楚,可以问我呀
      

  3.   

    提供一个思路,就是在TreeView初试化时先将这个树形目录的顶层和顶层的下一层的Node先填充好,这样就能在TreeView控件中显示出来最初试的顶层Node的内容(根据你的数据结构,取出顶层和次一层的记录,具体就不用说了吧),同时在TreeView控件中可以看见的任何一个Node的下一层的Node也已经填充好。
    现在我们要用到TreeView控件的expand事件,你可以在一个Node的expand事件中,遍历这个Node的所有子Node,将每个子Node的下一层Node的内容从数据库中读出来填充就来。这样,扩展了一个Node就会把这个Node的子Node的子Node的内容填充进来,保证了在TreeView控件中所看见的Node的子Node都已经填充好了,一层层的expand下去直至没有子Node为止。下面给你一段expand事件处理的例子代码,供参考:private void TreeClass_Expand(object sender, Microsoft.Web.UI.WebControls.TreeViewClickEventArgs e)
    {
        TreeNode myNode=TreeClass.GetNodeFromIndex(e.Node);  //TreeViewClickEventArgs.Node 属性选择的Node的index
        foreach(TreeNode mySubNode in myNode.Nodes)
        {
            if(mySubNode.Nodes.Count==0)
            {
                myConnection=new SqlConnection();
                myConnection.ConnectionString=connstr;
                myCommand=new SqlCommand();
                myCommand.Connection=myConnection;
                myCommand.CommandText="select id,name from tablename where parent='"+mySubNode.Type+"'";
                myConnection.Open();
                myReader=myCommand.ExecuteReader();
                TreeNode mySubSubNode;
                while(myReader.Read())
                {
                    mySubSubNode=new TreeNode();
                    mySubSubNode.Type=myReader["id"].ToString();
                    mySubSubNode.Text=myReader["name"].ToString();
                    mySubNode.Nodes.Add(mySubSubNode);
                }
                myReader.Close();
                myConnection.Close();
            }
        }
    }
      

  4.   

    下面的例子经过本人调试成功,如果你也调试成功请快结贴,我好升级到3个▲(可怜啊!看看别人都带上星了)。 数据库的表结构是cur_id,par_id,f_name.其中:所有的根结点的par_id为-1;而且所有的字段均为VARCHAR2类型。
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '在此处放置初始化页的用户代码
            If Not IsPostBack Then
               intiTree(TreeView2.Nodes, "-1")
            End If
        End Sub Private Sub intiTree(ByRef Nds As TreeNodeCollection, ByVal parentId As String)
            Dim sql As String = "select * from xj.treeview where par_id='" + parentId + "'"
            Dim myDataAdapter As New OleDbDataAdapter(sql, con)
            Dim ds As New DataSet()
            myDataAdapter.Fill(ds, "tree")
            Dim mydatable As DataTable
            mydatable = ds.Tables("tree")
            If mydatable.Rows.Count = 0 Then
                Exit Sub
            End If
            Dim drv As DataRowView
            Dim tmpNd As TreeNode
            For Each drv In mydatable.DefaultView
                tmpNd = New TreeNode()
                Dim strid As String
                strid = drv("CUR_ID")
                tmpNd.ID = strid
                tmpNd.Text = drv("F_NAME")
                Nds.Add(tmpNd)
                intiTree(tmpNd.Nodes, strid)
            Next
        End Sub
      

  5.   

    不好意思,诸位,我已经用Dictionary 保存一次读取的数据,然后通过递归调用实现了我想要的东西。代码也很简洁。
    给大家参考一下。
    <%
    Dim str_UserId '用户ID
    Dim str_Sql 'SQL语句
    Dim str_ErrKind '错误类型Dim obj_AimID '目标ID字典
    Dim obj_AimUpID '上级目标ID字典
    Dim obj_AimTitle '目标概要字典Dim str_AimID '目标ID临时变量
    Dim str_AimUpID '上级目标ID临时变量
    Dim str_AimTitle '目标概要临时变量str_UserId   = Request.Cookies("user_id") '用户IDSet obj_AimID     = Server.CreateObject("Scripting.Dictionary")
    Set obj_AimUpID   = Server.CreateObject("Scripting.Dictionary")
    Set obj_AimTitle  = Server.CreateObject("Scripting.Dictionary")
     
    If Trim(str_UserId) = "" Then
    Response.End
    End Ifstr_Sql  = " Select aim_id,aim_up_id,aim_title From " & sTBL_US_AIM & " Where user_id='" & str_UserId & "' order by aim_id"SqlConnect(str_Sql)
    Do While Not rst_Main.eof

    str_AimID = rst_Main("aim_id")
    str_AimUpID = rst_Main("aim_up_id")
    str_AimTitle = rst_Main("aim_title")

    If Not obj_AimID.Exists(str_AimID) Then
    obj_AimID.Add str_AimID,str_AimID
    obj_AimUpID.Add str_AimID,str_AimUpID
    obj_AimTitle.Add str_AimID,str_AimTitle
    End If

    rst_Main.MoveNext

    Loop
    SqlDisConnect'★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    'Purpose : FUNCTION SetSubAim
    'Inputs  : 1 i_str_aim_id string 目标ID
    'Returns : 设定当前目标的下级目标
    'Comments: 递归调用
    'Create  : By bbschat @ 2003.06
    '★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★Sub SetSubAim(ByVal i_str_aim_id)

    Dim objItem
    Dim s_flg

    s_flg = 0
    For Each objItem In obj_AimID
    If obj_AimUpID(objItem) = i_str_aim_id And obj_AimID(objItem) <> i_str_aim_id Then
    s_flg = 1
    End If
    Next

    If s_flg = 1 Then
    Response.write Chr(13) & "<UL>"
    For Each objItem In obj_AimID
    If obj_AimUpID(objItem) = i_str_aim_id And obj_AimID(objItem) <> i_str_aim_id Then
    Response.write Chr(13) & "<LI>"
    Response.write "<a href='aim_show?aim_id=" & objItem & "'>-"
    Response.write obj_AimTitle.Item(objItem) & "</a></LI>"
    Call SetSubAim(objItem)
    End If
    Next
    Response.write "</UL>"
    End If
    End Sub
    %><html>
    <head>
    <style TYPE="text/css">
    /* Outline Style Sheet */
    UL UL {display: none; margin-left: 20pt}
    </style><script LANGUAGE="JavaScript">
    <!--
    function checkParent(src, dest) {
    // Search for a specific parent of the current element
    while (src!=null) 
    {
    if (src.tagName == dest) return src;
    src = src.parentElement;
    }
    return null;
    }

            function outline() {     
            // Expand or collapse if a list item is clicked.
             var open = event.srcElement;
            // Make sure clicked inside an LI. This test allows rich HTML inside lists.
                var el = checkParent(open, "LI");
                if (null!=el) {
                  var pos = 0;
                  // Search for a nested list
                  for (var pos=0; pos<el.children.length; pos++) {
                    if ("UL"==el.children[pos].tagName) break;
                 }
                 if (pos==el.children.length) return;
               } else return;
               el = el.children[pos];
               if ("UL"==el.tagName) {
                 // Expand or Collapse nested list
                 if (""==el.style.display) {
                   el.style.display = "block"; 
                   el.style.listStyleImage = "url(images/folder.gif)";
                   el.parentElement.style.listStyleImage = "url(images/ofolder.gif)";
                 }
               else {
                   el.style.display = "";
                   el.parentElement.style.listStyleImage = "url(images/folder.gif)";
               }
             }
               event.cancelBubble = true;
            }
            document.onclick = outline;
    -->
    </script><base target="FRight">
    <title>目标列表</title>
    <meta http-equiv='Content-Type' content='text/html; charset=gb2312'>
    <LInk rel="stylesheet" type="text/css" href="../../css/style.css">
    </head><body background="../../img/bg.jpg">
    <%
    Response.write "<UL>"
    Response.write "<LI STYLE='list-style-image: url(images/folder.gif)'>"
    Response.write "<a href='aim_show.asp?aim_id=" & str_UserId & "'>-"
    Response.write obj_AimTitle.Item(str_UserId)
    Response.write "</a></LI>"Call SetSubAim(str_UserId)Response.write "</UL>"
    %></body>
    </html>