利用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>
<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>
既然是无限级菜单,肯定要用到递归来实现,于是就写了一个如下的递归算法
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);
}
}
{
//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";
}
{
//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);
}
}
{
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);
}
{
Microsoft.Web.UI.WebControls.TreeNode rootnode = new Microsoft.Web.UI.WebControls.TreeNode();
rootnode.Expanded = true;
TreeView2.Nodes.Add(rootnode);
CreateTree(0, rootnode);
}
这样就算大致实现了
另,数据库里的数据格式是这样的
-----------------------------------------
id text belong
1 aaaa 0
2 bbbb 0
3 cccc 0
4 dddd 1
5 eeee 2
6 ffff 4
posted on 2004-10-28 22:32 流浪的狗 阅读(16978) 评论(41) 编辑 收藏 引用 收藏至365Key 所属分类: Dotnet C#
评论
# re: 利用TreeView控件动态生成无限级树 2004-10-28 23:04 zfphere
好啊, 正想找这方面的资料呢。 回复
# re: 利用TreeView控件动态生成无限级树 2004-10-29 16:53 bomb_football
呵呵,请问楼主用你这方法能解决TreeView不闪的问题不 回复
# re: 利用TreeView控件动态生成无限级树 2004-10-29 18:27 边城浪子
不明白你说的闪是指什么?
如果我加上autopostback = true的属性后是会闪烁
因为每次点击都触发页面进行回传 回复
# re: 利用TreeView控件动态生成无限级树 2004-11-18 08:48 tyl
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);
} 回复
# re: 利用TreeView控件动态生成无限级树 2005-01-03 13:32 sys53
我觉生成xml还不如直接用可编程的方式好。 回复
# re: 利用TreeView控件动态生成无限级树 2005-04-01 13:37 simsong
楼主
我在递归那里有些不明白
发现虽然定义 belong
在函数里面一直没有用到呀
没有父节点如何作到遍历呀? 回复
# re: 利用TreeView控件动态生成无限级树 2005-04-03 13:40 边城浪子
@ simsong
belong是用来根据父节点的id来得到子节点
然后构造dataset的
上面我给省略掉了,忘了说明,不好意思 回复
# re: 利用TreeView控件动态生成无限级树 2005-04-07 10:52 qianqian
如何遍历整个treeView,来读取哪个节点被选中了(CheckBox)。
另外如何实现,当父节点被选中后,子节点都被选中。 回复
# re: 利用TreeView控件动态生成无限级树 2005-05-20 14:39 33
数据库连接池会用尽的哦。 回复
# re: 利用TreeView控件动态生成无限级树 2005-06-12 19:39 vb
如何用在vb.net使用treeview控件,其当点击它的时候调用数据库中的数据!!使数据显示在文本筐啊!!我是个出学者,希望能得到帮助!!
回复
# re: 利用TreeView控件动态生成无限级树 2005-06-25 14:21 bobyang008
我通过属性设置treenodesrc,直接在treenodesrc属性中填写符合要求的xml文件后何以实现绑定,但是为什么在编程是写代码:
treeview1.treenodesrc="xml文件"的形式却绑定不出来,有谁能告诉我为什么? 回复
# re: 利用TreeView控件动态生成无限级树 2005-07-01 11:34 小五
可不可以用ASP呀! 回复
# re: 利用TreeView控件动态生成无限级树 2005-07-07 16:53 windy
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控件动态生成无限级树 2005-07-23 16:01 haha
好啊,希望以后多发些同样的文章!!! 回复
# 为什么我的TreeView控件 出现此错误? 2005-07-25 11:21 yzuo
第三国vsd 回复
# 为什么我的TreeView控件 出现此错误,.net中的TreeView控件又长度限制吗? 2005-07-25 11:24 yqzuo
指定的参数已超出有效值的范围。参数名: 索引超出范围。必须为非负值并小于集合大小。
我是初学者,请各位多多指教!不胜感激! 回复
# re: 利用TreeView控件动态生成无限级树 2005-07-27 19:35 swx
楼主,直接用数据库绑定会产生一个问题,这就是:当数据表比较大时,采用B/S方式速度会很慢,我在做一个中国行政地区树形选单,3320个记录,分省/地区/县市三层,如果采用数据表(DATATABLE)动态添充TREEVIEW,和本地测试服务器间(100M)要90秒左右的时间,优化后也要9秒,在实际应用中没有意义,后来想到TREEVIEW控件支持XML文件绑定,而这样也不用频繁地读数据库,速度应该非常快。用了一个测试XML文件,大小57K,基本和“中国行政地区”字典差不多,速度却非常快,1秒左右吧。仅供参考。 回复
# re: 利用TreeView控件动态生成无限级树 2005-08-13 10:23 豪杰也许本疯子
VB6下TreeView的Nodes的index不能大于130吗?下面程序段出错,提示“35602"
Private Sub Form_Load()
'设置 Treeview 控件属性。
TreeView1.LineStyle = tvwRootLines ' Linestyle 1
'添加 Node 对象。
Dim nodX As Node '声明 Node 变量。
'带有文本 'Root' 的第一个节点。
Set nodX = TreeView1.Nodes.Add(, , "r", "Root")
'下一个节点是节点 1 ("Root") 的子节点。
Dim i As Integer
For i = 1 To 131
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "key" & Chr(i), i)
Next
End Sub
而下面却可以正常运行:
Private Sub Form_Load()
'设置 Treeview 控件属性。
TreeView1.LineStyle = tvwRootLines ' Linestyle 1
'添加 Node 对象。
Dim nodX As Node '声明 Node 变量。
'带有文本 'Root' 的第一个节点。
Set nodX = TreeView1.Nodes.Add(, , "r", "Root")
'下一个节点是节点 1 ("Root") 的子节点。
Dim i As Integer
For i = 1 To 129
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "key" & Chr(i), i)
Next
End Sub
为什么?有什么解决方法吗?因为我的程序要从数据库里填充TreeView. 回复
# re: 利用TreeView控件动态生成无限级树 2005-08-17 13:49 lee
我用这个控件老是绑定不上XML文件,XML文件的格式是按你那个样式写的
在ASPX中是这样的:
<iewc:treeview id="TreeView1" style="Z-INDEX: 101; LEFT: 264px; POSITION: absolute; TOP: 112px"
runat="server">
<iewc:TreeNode TreeNodeSrc="book.xml" Text="书名"></iewc:TreeNode>
</iewc:treeview></FONT></form>
你看有错没??
回复
# re: 利用TreeView控件动态生成无限级树 2005-08-25 17:09 SD-sharp
在学习 回复
# re: 利用TreeView控件动态生成无限级树 2005-09-02 09:55 kaixin
为什么我用这个不好用呢 回复
# re: 利用TreeView控件动态生成无限级树 2005-09-06 22:37 老钱
数据量一大就不行了。而且慢。
没有实用价值 回复
# re: 利用TreeView控件动态生成无限级树 2005-09-07 16:59 paopaotang
为什么我在代码里绑定xml文件,运行以后看不到展开的treeview,要刷新几次页面后,xml里面的数据才能正常显示呢?
如果在html中直接绑定xml文件就不会出现这种问题。
急!!!!!!!!!!!希望高手帮忙! 回复
# re: 利用TreeView控件动态生成无限级树 2005-09-27 10:38 懒猫
TreeView能不能和access数据库绑定呢?代码(C#)是怎么写的呢?谢谢楼主! 回复
# re: 利用TreeView控件动态生成无限级树 2005-10-20 09:30 yhj_ch
好呀!我也正想找这方面的资料!我是一个刚入门的!还不太明白怎么!请大家多多指教! 回复
# re: 利用TreeView控件动态生成无限级树 2005-10-20 09:30 yhj_ch
好呀!我也正想找这方面的资料!我是一个刚入门的!还不太明白怎么!请大家多多指教! 回复
# re: 利用TreeView控件动态生成无限级树 2005-11-15 15:08 lannicks
由于现在开始用asp.net 2005,以后需要用到树型控件,就研究了下。我不知道楼主的用的的是什么版本,asp.net 2005中,TreeView控件xml绑定的用法有些不太一样,后置代码动态绑定是完全可以的。以下是个人的做法:
脚本:
<div>
<asp:XmlDataSource ID="AreaDataSource" runat="server"/>
<asp:TreeView ID="AreaTreeView" runat="server" DataSourceID="AreaDataSource">
<DataBindings>
<asp:TreeNodeBinding DataMember="AreaId" TextField="#InnerText" />
<asp:TreeNodeBinding DataMember="Area" TextField="#InnerText" />
<asp:TreeNodeBinding DataMember="FatherId" TextField="#InnerText" />
</DataBindings>
</asp:TreeView>
</div>
代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
CreateXML();
TreeViewBind();
}
}
private void TreeViewBind()
{
AreaDataSource.DataFile = "~/App_Data/XML/AreaXml.xml";
AreaDataSource.XPath = "/NewDataSet/Table";
AreaTreeView.DataBind();
}
private void CreateXML()
{
string sql = "select AreaId,Area,FatherId from Example_Areas";
DataSet ds = new DataSet();
DBDealer db = new DBDealer();
ds = db.ExeSelectDS(sql);
string path = Server.MapPath("~/App_Data/XML/AreaXml.xml");
if (!File.Exists(path))
{
try
{
ds.WriteXml(path);
}
catch
{
throw new Exception("生成xml文件失败!");
}
finally
{
ds.Dispose();
}
}
}
我只是简单的使用DataSet生成一个Xml文件,然后直接绑定。可以根据楼主的生成一定样式的xml在进行绑定,然后做到分层。 回复
# re: 利用TreeView控件动态生成无限级树 2006-01-11 13:10 谢铁成
兄弟到我的网页上看我做的无限分级.那个效率比这个高. 回复
# re: 利用TreeView控件动态生成无限级树 2006-01-18 10:43 ghner
要想不闪,即不刷新,那就将一个包含treeview的页面单独放在iframe中 回复
# re: 利用TreeView控件动态生成无限级树 2006-01-27 00:31 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 QuickTech
对不起
我的根都没加
问题解决了
回复
# re: 利用TreeView控件动态生成无限级树 2006-02-09 17:32 奥法
当程序和数据交互比较频繁时用xml文件,如果交互有限可直接用程序绑定,因为用xml文件容易造成数据不统一,所以要分析选择方案 回复
# re: 利用TreeView控件动态生成无限级树 2006-03-07 14:17 一知半解
楼主及各位兄弟姐妹,你们好..我也正在做一个权限树,也用这种方法从数据库中调出数据实现了树,,,但我做这棵树的目的是想在选择某个用户的时候他的权限给表示出来,就是有权限的在前面打钩,,,但我现在的问题就是每当选择一个用户的时候就调用一次存储过程生成一棵树,这样树就多了,我只想要一棵树而选不同的用户的时候在同一棵树前面的设置改变就可以了,,这问题我想很久没办法了,请各位大哥们帮哈忙,先谢谢了....... 回复
# re: 利用TreeView控件动态生成无限级树 2006-04-12 15:55 tttttt
为什么 int id = int.Parse(dr["id"].ToString().Trim());
这句老是抱错,超出范围,溢出,是不是递归出现问题? 回复
# re: 利用TreeView控件动态生成无限级树 2006-05-19 08:55 人世间
@豪杰也许本疯子
Private Sub Form_Load()
'设置 Treeview 控件属性。
TreeView1.LineStyle = tvwRootLines ' Linestyle 1
'添加 Node 对象。
Dim nodX As Node '声明 Node 变量。
'带有文本 'Root' 的第一个节点。
Set nodX = TreeView1.Nodes.Add(, , "r", "Root")
'下一个节点是节点 1 ("Root") 的子节点。
Dim i As Integer
For i = 1 To 10000
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "key" & i, i)
Next
End Sub
将ch(i)改成i ,就可以啦!
不过这样只能实现二层节点,如果我想实现三层应该如写不写呢?
知道的朋友请加我QQ:46669953 谢谢
大于10000的方法: 回复
# re: 利用TreeView控件动态生成无限级树 2006-07-07 23:13 零度海洋
推荐一个学习.NET的好站点..
http://www.zero163.com/sortinfo.asp?Classid=45
asp.net2.0 最新最全的资料
各类.net三方控件..
回复
# re: 利用TreeView控件动态生成无限级树 2006-09-10 14:10 pkmark
我在读取数据库时 用以下语句
"SELECT * FROM [TreeViewRoot] WHERE [belong] =" + Convert.ToString(belong)
应该可以调出需要的节点.
但是在编译时工具弹出错误信息,说foreach中的rootnode不存在,为何会这样?
那该如何在foreach内调用到该rootnode?
回复
# re: 利用TreeView控件动态生成无限级树 2006-09-10 15:00 pkmark
@pkmark
找到问题所在了原来.net的framework2.0 的treenode 的参数名变了,改成
rootnode.ChildNodes.Add(treenode);就OK啦!
回复
# re: 利用TreeView控件动态生成无限级树 2006-09-15 14:25 陈先生
短信二次开发数据库接口(一台电脑,一个短信猫,一个接口,无需上网,实现短信收发)
通过本数据库接口,能使你现有的系统(如OA、CRM、ERP等系统)轻松实现无线办公功能,无论你用的是哪种开发语言(VB\VC\VFP\asp\jsp\java\pb\delphi...),只要你的系统能读MS SQL 2000 或 Access数据库即可对接!你仅需要在指定的表中添加记录,本接口程序就自动进行发送及接收了,所以,您不需要了解任何有关数据通信方面的知识,就可实现手机短信的收发等功能!
深圳方寸科技有限公司,短信群发,短信猫(gsm modem)销售,
http://www.fcwww.com
qq:393376247
回复
# re: 利用TreeView控件动态生成无限级树 2006-10-04 17:23 TREEVIEW
LZ,帮俺解决下问题,,用TREEVIEW时,,如果点击节点时下一级的子节点会缩进,
当缩进后,他整体的板块也缩进,
用什么方法控制整体的板块固定大小 回复
# re: 利用TreeView控件动态生成无限级树 2006-10-14 10:23 手机语音自动应答软件 自动应答 播放语音 挂掉电话 (应答语音自己随心录制) 自动应答,收集手机用
好,不错 回复