ASP.NET学习社区

首页 » ASP.NET学习区 » 大学水平 » 如何用ASP.NET+SQL实现动态无限制级树
xiaoshunhua - 2008-7-9 15:58:00
如何用ASP.NET+SQL实现动态无限制级树请大虾指教
ztwjsq - 2008-7-9 16:04:00
没有例子?
asp.net - 2008-7-10 6:38:00
public partial class AdvAcordTree : System.Web.UI.Page
{
SysInfo sysInfo = new SysInfo();
DES des = new DES();
string patid;
DataSet ds; protected void Page_Load(object sender, EventArgs e)
{
patid = Request["patid"];
if (ds == null)
{
ds = new AdvAcord().GetMenuTree(sysInfo.ActDeptId, sysInfo.StaffId);
}
if (!IsPostBack)
{
TreeInit();
} } /// %26lt;summary>
/// 无刷新动态生成树
/// %26lt;/summary>
private void TreeInit()
{ http://aspx1.com
this.Tvtree.Nodes.Clear();

//添加个人模板
TreeNode node = new TreeNode("本人", "30");
node.SelectAction = TreeNodeSelectAction.Expand;
node.PopulateOnDemand = true;
this.Tvtree.Nodes.Add(node);

//添加本科模板
node = new TreeNode("本科", "20");
node.SelectAction = TreeNodeSelectAction.Expand;
node.PopulateOnDemand = true;
this.Tvtree.Nodes.Add(node);

//添加全院模板
node = new TreeNode("全院", "10");
node.SelectAction = TreeNodeSelectAction.Expand;
node.PopulateOnDemand = true;
this.Tvtree.Nodes.Add(node);
}

public void TreeShow(object sender, TreeNodeEventArgs e)
{
if (IsCallback)
if (e.Node.ChildNodes.Count == 0)
{
LoadChildNode(e.Node,int.Parse(e.Node.Value));
}
}

private void LoadChildNode(TreeNode node, Int32 id)
{
DataView dv = ds.Tables[0].DefaultView; 字串7
dv.RowFilter = string.Format(" sharekd = {0} ", id);
foreach (DataRowView drv in dv)
{
TreeNode nNew = new TreeNode();
nNew.Text = drv[GRPRCPPData.NAME_FIELD].ToString();
nNew.NavigateUrl = string.Format("AdvAcord.aspx?patid={0}%26amp;id={1}",
patid, des.Encrypt(drv[GRPRCPPData.ID_FIELD].ToString()));
node.ChildNodes.Add(nNew);
}
}
} 字串6
asp.net - 2008-7-10 6:39:00
利用TreeView控件动态生成无限级树


项目需要,有一个树形菜单需要动态生成,联想到TreeView控件,决定用TreeView来实现

首先注意到了TreeView控件有一个属性TreeNodeSrc
这个属性可以指定一个固定格式的xml文件
<?xml version="1.0" encoding="utf-8" ?>
<TREENODES>
    <TREENODE text="aaaaaaaa" CheckBox="true"></TREENODE>
    <TREENODE text="bbbbbbbb" CheckBox="true"></TREENODE>
    <TREENODE text="cccccccccc" EXPANDED="true" CheckBox="true">
        <TREENODE text="ddddddddd" CheckBox="true"></TREENODE>
        <TREENODE text="eeeeeeeee" CheckBox="true"></TREENODE>
    </TREENODE>
    <TREENODE text="fffffffffffff" CheckBox="true"></TREENODE>
</TREENODES>于是就想把数据库里的文件读出来写入一个xml文件中,然后再进行绑定
既然是无限级菜单,肯定要用到递归来实现,于是就写了一个如下的递归算法
private void CreateXml(XmlDocument objXMLDoc, XmlElement objRootElem, int belong)
        {
            //Get DataSet 这里的DataSet具体获取方法我省略掉了
            DataSet ds = new DataSet();
           
            foreach(DataRow dr in ds.Tables[0].Rows)
            {
                //Create ChildNode TreeNode
                XmlElement objXmlElem = objXMLDoc.CreateElement("TREENODE");
                objRootElem.AppendChild(objXmlElem);

                //Create Attributes Text
                XmlAttribute objXmlAttText = objXMLDoc.CreateAttribute("Text");
                objXmlAttText.Value = dr["text"].ToString().Trim();
                objXmlElem.SetAttributeNode(objXmlAttText);

                //Create Attributes CheckBox
                XmlAttribute objXmlAttCB = objXMLDoc.CreateAttribute("CheckBox");
                objXmlAttCB.Value = "True";
                objXmlElem.SetAttributeNode(objXmlAttCB);

                int id = int.Parse(dr["id"].ToString().Trim());
                CreateXml(objXMLDoc, objXmlElem, id);
            }
        }
然后用下面的方法来实现绑定
private void BindXmlTree()
        {
            //Create Xml File
            XmlDocument objXmlDoc = new XmlDocument();

            //Insert Xml Declaration
            XmlDeclaration objXmlDeclare = objXmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
            objXmlDoc.InsertBefore(objXmlDeclare, objXmlDoc.DocumentElement);

            XmlElement objRootElem = objXmlDoc.CreateElement("TREENODES");
            objXmlDoc.AppendChild(objRootElem);

            CreateXml(objXmlDoc, objRootElem, 0);

            objXmlDoc.Save("E:\\TreeMenu.xml");
            TreeView2.TreeNodeSrc = "TreeMenu.xml";
        }
到最后两行我就停住了,因为问题出现了
生成的objXmlDoc文件不知道用什么方式才能绑定上TreeNodeSrc
我试了试直接 TreeView2.TreeNodeSrc = objXmlDoc;
可是TreeNodeSrc是String型的数据,没办法
有没有什么方法可以不保存这个objXmlDoc文件而直接绑定呢?

于是就换了个办法来实现
TreeView有一个节点控件叫TreeNode,直接把数据给TreeNode上


private void CreateTree(int belong, Microsoft.Web.UI.WebControls.TreeNode rootnode)
        {
            DataSet ds = new DataSet();

            foreach(DataRow dr in ds.Tables[0].Rows)
            {
                Microsoft.Web.UI.WebControls.TreeNode treenode = new Microsoft.Web.UI.WebControls.TreeNode();
                treenode.Text = dr["text"].ToString().Trim();
                treenode.CheckBox = true;
                treenode.Expanded = true;
                rootnode.Nodes.Add(treenode);

                int id = int.Parse(dr["id"].ToString().Trim());
                CreateTree(id, treenode);
            }
        }
用的是一样的递归思想,而且我发现这样做还比较简单一些,很多TreeNode自带的属性很方便修改
如果用Xml还要手动去添加每一个属性,麻烦
在PageLoad里触发这个方法
private void Page_Load(object sender, System.EventArgs e)
        {
            Microsoft.Web.UI.WebControls.TreeNode rootnode = new Microsoft.Web.UI.WebControls.TreeNode();
            rootnode.Expanded = true;
            TreeView2.Nodes.Add(rootnode);
            CreateTree(0, rootnode);
        }注意,这里为了实现递归,不得不添加一个空的根节点rootnode

这样就算大致实现了
另,数据库里的数据格式是这样的
-----------------------------------------
id                    text                    belong
1                    aaaa                    0
2                    bbbb                  0
3                    cccc                    0
4                    dddd                    1
5                    eeee                    2
6                    ffff                        4



==========================================


private void InitTree(TreeNodeCollection Nds,string parentId)
{
TreeNode tmpNd;
DataRow[] rows = data.Tables[0].Select("ParentId='" + parentId + "'");
foreach(DataRow row in rows)
{
tmpNd = new TreeNode();
tmpNd.ID = row["NodeId"].ToString();
tmpNd.Text = row["NodeName"].ToString();
tmpNd.NavigateUrl = row["Url"].ToString();
Nds.Add(tmpNd);
if (row["NodeId"].ToString()!="2")
InitTree(tmpNd.Nodes, tmpNd.ID);
}

============================================



# re: 利用TreeView控件动态生成无限级树  回复   
2006-01-27 00:31 by QuickTech
Private Sub LoadTrv()
Dim Root As New Microsoft.Web.UI.WebControls.TreeNode
Root.Text = "ALL:"
Root.ImageUrl = "../images/trv_root.gif"
Root.SelectedImageUrl = "../images/trv_root.gif"
Root.ExpandedImageUrl = "../images/trv_root.gif"

Dim db As New DB
Dim con As SqlClient.SqlConnection = New SqlClient.SqlConnection(db.Constr)
Dim dr As SqlClient.SqlDataReader
Dim SQL As String = "select Floor_value,Floor_Title from basic_floor order by floor_value"
Dim cmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(SQL, con)
con.Open()
dr = cmd.ExecuteReader
While dr.Read
Dim FloorNd As New Microsoft.Web.UI.WebControls.TreeNode
FloorNd.Text = dr("Floor_value") & ":" & dr("Floor_Title")
FloorNd.ImageUrl = "../images/TrvST2.bmp"
FloorNd.SelectedImageUrl = "../images/trvst10.bmp"
FloorNd.ExpandedImageUrl = "../images/trvst1.bmp"
Root.Nodes.Add(FloorNd)
End While
dr.Close()
con.Close()
con.Dispose()
cmd.Dispose()
End Sub

为什么我的代码不能显示呢?????????
# re: 利用TreeView控件动态生成无限级树  回复   
2006-01-27 00:34 by QuickTech
对不起
我的根都没加
问题解决了
zorosuteng - 2008-7-10 8:02:00
请查看我的帖子 http://i.aspx1.com/showtopic-1255.htm 
源码例子在附件 sqlserver  Dataset绑定TreeView 实现无限级树形菜单
libihuan - 2008-7-10 11:04:00
恩不错 我也学习了哈
weer123 - 2008-7-12 9:32:00
<iewc:TreeView runat="server" ID="Treeview1" NAME="Treeview1">
<iewc:TreeNode id="Treenode1" runat="server" TreeNodeSrc="menuone.txt" Expanded="True" Text="信息类别列表">
</iewc:TreeNode>
</iewc:TreeView>  
  其中menuone.txt的内容如下:  

<TREENODES>
<treenode text='蔬菜' NavigateUrl='xxcb_add.aspx?classname=蔬菜&classid=01'? Target='main1'>
  <treenode text='白菜' NavigateUrl='xxcb_add.aspx?classname=白菜&classid=0101'?? Target='main1'/>
  <treenode text='萝卜' NavigateUrl='xxcb_add.aspx?classname=萝卜&classid=0102'?? Target='main1'/>
  <treenode text='黄花菜' NavigateUrl='xxcb_add.aspx?classname=黄花菜&classid=0103'?? Target='main1'/>
</treenode>
<treenode text='水果' NavigateUrl='xxcb_add.aspx?classname=水果&classid=02'? Target='main1'>
  <treenode text='苹果' NavigateUrl='xxcb_add.aspx?classname=苹果&classid=0201'? Target='main1'>
  <treenode text='红富士' NavigateUrl='xxcb_add.aspx?classname=红富士&classid=020101'?? Target='main1'/>
<treenode text='其它苹果' NavigateUrl='xxcb_add.aspx?classname=其它苹果&classid=020102'?? Target='main1'/>  
</treenode>
  <treenode text='桃子' NavigateUrl='xxcb_add.aspx?classname=桃子&classid=0202'?? Target='main1'/>
  <treenode text='荔枝' NavigateUrl='xxcb_add.aspx?classname=荔枝&classid=0203'?? Target='main1'/>
</treenode>
<treenode text='粮食' NavigateUrl='xxcb_add.aspx?classname=粮食&classid=03'? Target='main1'>
  <treenode text='大米' NavigateUrl='xxcb_add.aspx?classname=大米&classid=0301'?? Target='main1'/>
  <treenode text='玉米' NavigateUrl='xxcb_add.aspx?classname=玉米&classid=0302'?? Target='main1'/>
</treenode>
</TREENODES>  
  现在的问题变成了如何将数据表根据“类别号”修改menuone.txt文件。将该过程放在对数据表修改后进行。下面是根据表的内容生成menuone.txt的源代码:  

Imports System.IO
Dim txtwriter As StreamWriter
txtwriter = File.CreateText(Server.MapPathstrpath ("\menuone.txt"))
txtwriter.WriteLine("<TREENODES>")
Dim objConn As OleDbConnection
Dim objCmd As OleDbCommand
Dim objRead As OleDbDataReader
Dim strSQL, strDSN As String
Dim strid, strname, strid1, strname1 As String
Dim strand As String
strand = "&"  
Dim i, j, k, m As Integer
i = 0
j = 0
k = 0
m = 0
strSQL = "select * from class order by classid "
objConn = New OleDbConnection(ConfigurationSettings.AppSettings("connString"))
objCmd = New OleDbCommand(strSQL, objConn)
objCmd.Connection.Open()
objRead = objCmd.ExecuteReader()
While objRead.Read() 
  If j = 0 Then
  j = Len(Trim(objRead.Item("classid")))
  Else
  strid = strid1
  strname = strname1
  i = Len(Trim(objRead.Item("classid")))
  k = i - j
  Select Case k
  Case Is > 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'>")
  Case Is = 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'/>")
  Case Is < 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'/>")
  'txtwriter.WriteLine("</treenode>")
  m = k
  While m < 0
  txtwriter.WriteLine("</treenode>")
  m = m + 2
  End While
  End Select
  j = Len(Trim(objRead.Item("classid")))
  End If 
  strid1 = Trim(objRead.Item("classid"))
  strname1 = Trim(objRead.Item("classname"))
  End While  
  'strid = strid1
  'strname = strname1
  i = Len(strid)
  k = j - i
  strid = strid1
  strname = strname1
  Select Case k
  Case Is > 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'/>")
  'txtwriter.WriteLine("</treenode>")
  m = Len(strid) / 2
  While m > 1
  txtwriter.WriteLine("</treenode>")
  m = m - 1
  End While
  Case Is = 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'/>")
  'txtwriter.WriteLine("</treenode>")
  m = Len(strid) / 2
  While m > 1
  txtwriter.WriteLine("</treenode>")
  m = m - 1
  End While
  Case Is <= 0
  txtwriter.WriteLine("<treenode text='" & strname & "' NavigateUrl='xxcb_add.aspx?classname=" & strname & "" & strand & "classid=" & strid & "' Target='main1'/>")
  'txtwriter.WriteLine("</treenode>")
  m = Len(strid) / 2
  While m > 1
  txtwriter.WriteLine("</treenode>")
  m = m - 1
  End While
  End Select
  txtwriter.WriteLine("</TREENODES>")
  txtwriter.Close()  
  这样menuone.txt就按要求生成了菜单源文件。 
zhengqzheng - 2008-7-13 22:47:00
好像比较深奥。。
1
查看完整版本: 如何用ASP.NET+SQL实现动态无限制级树