现在
ASP.NET2.0
即将发布正式版,我们--
ASP.NET2.0
的开发人员――早已对它感兴趣。随着新框架的推出,
ASP.NET2.0
内置了一系列新的控件。在这些控件里,我个人较为喜欢的一个控件是
TreeView
控件。(
本文发表于
2005/10/31
日,微软
ASP.NET2.0
于
2005/11/7
日正式推出,所以有上面的“即将发布正式版”一说
)
微软曾经在
ASP.NET2.0
的前版本(
ASP.NET1.X
版)开放了一个开源代码控件--
IE Web Control
,在该控件的基础上并吸收来自各方反馈,微软推出了基于
.NET2.0
的
TreeView
控件。
TreeView
并不仅仅被重写,它还包括一系列新的特性,例如它支持客户端的执行,节点的动态填充,事件回发,链接导航。
例子
我准备提供一个简单的例子来说明如何使用
TreeView
控件显示
SQL Server
数据库里的分层数据。完成分层这个工具并不需要数据库的额外支持,也就是
TreeView
应该捕获数据的分层结构来进行显示--不论数据到底分了几层
我们假设有一个名称为
TreeViewSampleDB
数据库,其中包含
SampleCategories
数据库,该数据表结构如下:
注意:本例使用
现在,我们使用了
TreeViewVB.aspx
页面,下面的代码显示了对
TreeView
的使用
<
asp:TreeView
ID
="TreeView1"
ExpandDepth
="0"
PopulateNodesFromClient
="true"
ShowLines
="true"
ShowExpandCollapse
="true"
runat
="server"
/>
这段代码意味这我们设置
TreeView
的初始化伸展深度是一级节点。我们想使用客户端节点执行特殊的功能以便我们能够给我们的客户更好的提供使用服务。注意这里并未使用客户端回发。另外,如果节点有子节点,我们同样想在父节点和子节点之间显示连接线,并且使用
伸展
/
收缩
图标显示节点的状态。
下一步,我们查看一下后台代码文件
TreeViewVB.aspx.vb
。我们使用代码完成根节点的显示,下面是部分代码:
ProtectedSub Page_Load(ByVal sender AsObject, ByVal e As System.EventArgs) HandlesMe.Load
IfNot Page.IsPostBack Then
PopulateRootLevel()
EndIf
EndSub
PrivateSub PopulateRootLevel()
Dim objConn AsNew SqlConnection(_
"server=JOTEKE/SQLExpress;Trusted_Connection=true;DATABASE=TreeViewSampleDB")
Dim objCommand AsNew SqlCommand("select id,title,(select count(*) FROM SampleCategories " _
& "WHERE parentid=sc.id) childnodecount FROM SampleCategories sc where parentID IS NULL", _
objConn)
Dim da AsNew SqlDataAdapter(objCommand)
Dim dt AsNew DataTable()
da.Fill(dt)
PopulateNodes(dt, TreeView1.Nodes)
EndSub
上面操作包括连接数据库,查询第一层节点(也就是父节点的
ID
为
null
),并利用
PopulateNodes
方法建立
TreeNode
对象,
PopulateNodes
代码如下:
Private
Sub
PopulateNodes(
ByVal
dt
As
DataTable, _
ByVal
nodes
As
TreeNodeCollection)
For
Each
dr
As
DataRow
In
dt.Rows
Dim
tn
As
New
TreeNode()
tn.Text
=
dr(
"title"
).ToString()
tn.Value
=
dr(
"id"
).ToString()
nodes.
Add
(tn)
'If node has child nodes, then enable on-demand populating
tn.PopulateOnDemand
=
(
CInt
(dr(
"childnodecount"
)) > 0)
Next
End
Sub
这段代码是重要的逻辑处理片段,
PopulateNodes
方法循环
DataTable
里的所有行,并且如果给定的节点具有子节点,它将设置
PopulateOnDemand
属性为
true
。这样如果节点具有子节点,将使用
伸展
/
收缩
图标进行状态显示。
下一步,我们建立代码给定节点的子节点,也就是用户单击父节点的子节点,代码如下
Private
Sub
PopulateSubLevel(
ByVal
parentid
As
Integer
, _
ByVal
parentNode
As
TreeNode)
Dim
objConn
As
New
SqlConnection(_
"server=JOTEKE/SQLExpress;Trusted_Connection=true;DATABASE=TreeViewSampleDB"
)
Dim
objCommand
As
New
SqlCommand(
"select id,title,(select count(*) FROM SampleCategories "
_
&
"WHERE parentid=sc.id) childnodecount FROM SampleCategories sc where parentID=@parentID"
, _
objConn)
objCommand.Parameters.
Add
(
"@parentID"
, SqlDbType.
Int
).Value
=
parentid
Dim
da
As
New
SqlDataAdapter(objCommand)
Dim
dt
As
New
DataTable()
da.Fill(dt)
PopulateNodes(dt, parentNode.ChildNodes)
End
Sub
上面代码片段执行的思路和
Root
定级一样,不过稍微的区别是只有给定的子节点进行查询和填充,触发指定节点的事件如下:
Protected
Sub
TreeView1_TreeNodePopulate(
ByVal
sender
As
Object
, _
ByVal
e
As
System.Web.UI.WebControls.TreeNodeEventArgs)
Handles
TreeView1.TreeNodePopulate
PopulateSubLevel(
CInt
(e.Node.Value), e.Node)
End
Sub
也就是,当触发
OnTreeNodePopulate
事件时,执行
TreeView1_TreeNodePopulate
方法(
OnTreeNodePopulate="TreeView1_TreeNodePopulate"
),
TreeNodePopulate
事件将在用户第一次展开父节点时触发。由于
PopulateNodesFromClient
(
TreeView
)和
PopulateOnDemand
(
TreeNode
)的设置,这样使得
ASP.NET
页面框架能够捕获客户端的回调,这使得完成回调并不一定非要数据回发。并且由于
ASP.NET2.0
提供的更好的跨浏览器支持,这样的工作在其它浏览器里,例如
FireFox
中,工作的也很好。
注意:用户单击节点并未导致数据的回发,因为我并未修改选择节点的数据。
到此,运行上面结果,可以看到运行结果如下图
这段代码涉及
TreeView
两个成员,您可以到
MSDN
查看它们的说明:
TreeView.OnTreeNodePopulate
方法
TreeView.PopulateNodesFromClient
属性
总结
到这里我们相当简单的完成了
TreeView
的演示。这个方法需要一些编码,当然在使用
TreeView
显示分层数据方面编码并不是必须的。
在显示分层数据方面,对于代码的编写,
TreeView
给我们提供了很大的活动控件。不过,我相信通过代码了解
TreeView
技术是学习它的最好方式。
代码下载
本文源代码附带了
VB
和
C#
语言两个版本。运行时可以运行
TreeViewDBSQLSchema.sql
和
TreeViewDBSQLData.sql
建立数据库,也可以使用
TreeViewSampleDB.BAK
文件还原数据库。单击下面链接下载本文源代码
源文地址
SQL Server2000
数据库,如果您使用的是
SQL Server2005
或者
SQL 2000
以前版本的数据库,本例子同样适用。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1431283