ASP.NET中樹形圖的實(shí)現(xiàn)
2024-07-10 12:57:04
供稿:網(wǎng)友
 
 
樹形圖用于顯示按照樹形結(jié)構(gòu)進(jìn)行組織的數(shù)據(jù),其用途比較廣泛,如計(jì)算機(jī)中的文件系統(tǒng)(windows中的資源管理器)、企業(yè)或公司的組成結(jié)構(gòu)等。我們知道在windows下vb、pb、delphi等工具提供了一個功能很強(qiáng)的樹型控件treeview,利用treeview控件可以方便地開發(fā)樹形圖。然而在網(wǎng)頁上實(shí)現(xiàn)樹形圖就不那么容易了,現(xiàn)在在asp.net中利用微軟提供的internet explorer webcontrols它使得網(wǎng)頁上的樹形圖開發(fā)與在windows下一樣的方便,一樣的功能強(qiáng)大,甚至更靈活。 
本文介紹用internet explorer webcontrols開發(fā)樹形圖的方法,由于樹形圖結(jié)構(gòu)較復(fù)雜,使用起來常不知如何下手。筆者結(jié)合最近剛為公司用asp.net編寫的應(yīng)用程序管理器這一具體實(shí)例,詳細(xì)闡述在asp.net下如何將internet explorer webcontrols的使用與數(shù)據(jù)庫聯(lián)系起來,實(shí)現(xiàn)數(shù)據(jù)分任意多層顯示,方便地進(jìn)行增加、修改、刪除、移動操作。筆者希望通過對該實(shí)例的闡述,達(dá)到拋磚引玉的效果,與各位同仁相互交流,共同進(jìn)步。 
internet explorer webcontrols不在vs.net的標(biāo)準(zhǔn)server control中,要到微軟的站點(diǎn)上下載,下載地址是: 
http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/asp_dot_net_servercontrols/webcontrols/default.asp 
下載安裝后第一次使用時,要右擊工具箱customize toolbox…→.net framework components中找到micosoft.web.ui.webcontrols.treeview后選中,這樣treeview控件就出現(xiàn)在工具箱中了。 
一、樹的建立 
具體方法是:創(chuàng)建一個數(shù)據(jù)庫,設(shè)計(jì)樹圖信息表tree_info,包含nodeid、parentid、nodename、adderss、icon字段,其它字段根據(jù)實(shí)際業(yè)務(wù)而定,節(jié)點(diǎn)名稱nodename將在樹型控件的節(jié)點(diǎn)上顯示,nodeid字段保存節(jié)點(diǎn)的唯一標(biāo)識號,parentid表示當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)號,標(biāo)識號組成了一個“鏈表”,記錄了樹上節(jié)點(diǎn)的結(jié)構(gòu)。設(shè)計(jì)一個web窗體其上放置treeview控件。 
private sub createdataset()’建立數(shù)據(jù)集 
dim myconn as new sqlconnection() 
dim mycmd as new sqlcommand("select nodeid,nodename,parentid,address,icon from tree_info", myconn) 
dim mydataadapter as new sqldataadapter() 
myconn.connectionstring = application("connectstring") 
mycmd.commandtext = "" 
mycmd.connection = myconn 
mydataadapter.selectcommand = mycmd 
mydataadapter.fill(ds, "tree") 
end sub 
建樹的基本思路是:從根節(jié)點(diǎn)開始遞歸調(diào)用顯示子樹 
private sub page_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load 
createdataset() 
intitree(treeview1.nodes, 0) 
end sub 
private sub intitree(byref nds as treenodecollection, byval parentid as integer) 
dim dv as new dataview() 
dim drv as datarowview 
dim tmpnd as treenode 
dim intid as integer 
dv.table = ds.tables("tree") 
dv.rowfilter = "parentid=’" & parentid & "’" 
for each drv in dv 
tmpnd = new treenode() 
strid = drv("node_id") 
tmpnd.id = strid 
tmpnd.text = drv("node_name ") 
tmpnd.imageurl = drv("icon").tostring 
nds.add(tmpnd) 
intitree(nds(nds.count - 1).nodes, intid) 
next 
end sub 
二、增加、刪除樹節(jié)點(diǎn) 
單純在treeview 上增加、刪除、修改節(jié)點(diǎn)只需用nodes屬性的add、 remove、等方法即可,值得注意的地方是vs.net中treeview的nodes集合與vs6.0中的區(qū)別,vs6.0中的是一個大的集合,而vs.net中的是分層的每個node下都有nodes屬性。增加、刪除、修改樹節(jié)點(diǎn)時與vs6.0相比有很大差別,特別是刪除時。 
private sub butadd_click(byval sender as system.object, byval e as system.eventargs) handles butadd.click’在選定的節(jié)點(diǎn)下添加子節(jié)點(diǎn) 
dim tmpnd as new treenode(), ndsel as treenode 
tmpnd.id = getnewid() 
ndsel = treeview1.getnodefromindex(treeview1.selectednodeindex)’選中的節(jié)點(diǎn) 
tmpnd.text = "新節(jié)點(diǎn)" 
ndsel.nodes.add(tmpnd) 
dim myrow as datarow 
myrow = ds.tables("tree").newrow() 
myrow("node_name") = tmpnd.id 
myrow("node_descript") = "新節(jié)點(diǎn)" & tmpnd.id & "_" & ndsel.id 
myrow("parent_name") = ndsel.id 
ds.tables("tree").rows.add(myrow) 
end sub 
private sub butdele_click(byval sender as object, byval e as system.eventargs) handles butdele.click’刪除選中的節(jié)點(diǎn) 
dim idx as string = treeview1.selectednodeindex() 
getndcol(idx).remove(treeview1.getnodefromindex(idx)) 
dim dv as new dataview(), recno as integer 
dv.table = ds.tables("tree") 
dv.rowfilter= "nodeid=" & ndid 
dv.delete(0) 
end sub 
private function getndcol(byval idx as string) as treenodecollection 
‘獲得選中節(jié)點(diǎn)的父節(jié)點(diǎn)的nodes集合 
dim cnt as integer, i as integer 
dim tmpnds as treenodecollection 
dim idxs() as string 
idxs = split(idx, ".") 
cnt = ubound(idxs) 
if cnt = 0 then 
tmpnds = treeview1.nodes 
else 
tmpnds = treeview1.nodes(cint(idxs(0))).nodes 
for i = 1 to cnt - 1 
tmpnds = tmpnds(cint(idxs(i))).nodes 
next 
end if 
return tmpnds 
end function 
三、修改、移動樹節(jié)點(diǎn) 
由于服務(wù)器控件不支持鼠標(biāo)拖動事件,所以不能象windows程序那樣通過拖動移動節(jié)點(diǎn),這里是通過選擇父節(jié)點(diǎn)的方式。移動是通過在原位置刪除,新位置添加實(shí)現(xiàn)的,要注意在刪除時先保存節(jié)點(diǎn)信息。 
private sub treeview1_selectedindexchange(byval sender as object, byval e as microsoft.web.ui.webcontrols.treeviewselecteventargs) handles treeview1.selectedindexchange 
dim dv as new dataview() 
dv.table = ds.tables("tree") 
dim tmpnd as treenode = treendsel(e.oldnode), tmpnds as treenodecollection 
dv.rowfilter= "nodeid=" & tmpnd.id 
dv(0)("node_descript") = me.textbox1.text 
dv(0)("address") = me.textbox2.text 
dv(0)("target") = me.textbox3.text 
dv(0)("icon") = me.textbox4.text 
if dv(0)("parentid").tostring <> me.dropdownlist1.selecteditem.value then 
‘移動節(jié)點(diǎn) 
dv(0)("parent_name") = me.dropdownlist1.selecteditem.value 
if me.dropdownlist1.selecteditem.value = "root" then 
tmpnds = treeview1.nodes 
else 
tmpnds = fromidtonode(me.dropdownlist1.selecteditem.value, treeview1.nodes).nodes’新的父節(jié)點(diǎn)的nodes集合 
end if 
getndcol(e.oldnode).remove(tmpnd) 
tmpnds.add(tmpnd) 
end if 
tmpnd.text = me.textbox1.text 
tmpnd.imageurl = me.textbox4.text 
tmpnd = treeview1.getnodefromindex(treeview1.selectednodeindex) 
dv.rowfilter= "nodeid=" & tmpnd.id 
me.textbox1.text = dv(0)("nodename").tostring 
me.textbox2.text = dv(0)("address").tostring 
me.textbox3.text = dv(0)("target").tostring 
me.textbox4.text = dv(0)("icon").tostring 
end sub 
private function fromidtonode(byval id as string, byval nds as treenodecollection) as treenode 
‘由關(guān)鍵字查找節(jié)點(diǎn) 
dim i as integer 
dim tmpnd as treenode, tmpnd1 as treenode 
for each tmpnd in nds 
if tmpnd.id = id then 
return tmpnd 
exit function 
end if 
tmpnd1 = fromidtonode(id, tmpnd.nodes) 
if not (tmpnd1 is nothing) then 
return tmpnd1 
exit function 
end if 
next 
return nothing 
end function 
四、結(jié)束語 
以上闡述asp.net中樹狀顯示的基本方法,以及如何在對樹節(jié)點(diǎn)進(jìn)行維護(hù)(增加、刪除、修改、移動)的同時,修改數(shù)據(jù)庫數(shù)據(jù)。由于篇幅所限,筆者在此只對基本思路和流程及關(guān)鍵步驟作了介紹,并未列出詳細(xì)源代碼,讀者可自行完善。需要詳細(xì)源代碼者可與我聯(lián)系,本文程序在vs.net、sqlserver、windows 2000、iis5.0下調(diào)試通過。