自动从自引用表中绑定 Treeview 控件

分享于 

6分钟阅读

Web开发

  繁體
Screenshot - AutoBindingTreeView.gif

介绍

本文将展示如何实现自定义 ASP.NET TreeView 控件,该控件支持自引用 table的自动绑定。 控件支持从数据源控件绑定或者以编程方式使用数据源属性。

背景

本文是我以前文章的延续,展示了 TreeView 控件缺乏的有用功能。 前一篇文章展示了如何应用CSS并向树节点添加定制属性。 本文讨论了从自引用 table 中自动绑定 TreeView 控件的方法。

什么是自引用表?

自引用 table 包含它的列引用同一 table 中另一列的关系。 例如:

Self Referencing table

在图 上面 中,父ID列引用ID列表示父标识是形成分层数据的ID。

自动绑定

ASP.NET TreeView 只支持分层数据源控件。 为了解决这个问题,我们创建了一个数据绑定控件类 AutoBindingTree,它扩展了基类 DataBoundControl,以便我们可以覆盖 PerformSelectPerformDataBinding 事件。 在这里单击 有关创建自定义数据绑定控件的更多信息,请参见。

PerformDataBinding 接受 IEnumerable 作为表示从数据源检索到的数据的参数。 这里参数用于创建 DataView,因为它实现了 IEnumerable。 然后使用 DataView 创建一个保持自引用关系并被用于填充 TreeViewDataSetDataSet 使用三个强制属性:

  • DataTextField: 保存节点 Text 值的列的名称
  • DataFieldID: 保存 ID 值的列的名称
  • DataFieldParentID: 保存 ParentID 值的列的名称
ProtectedOverridesSub PerformDataBinding(ByVal oSourceData As IEnumerable)
 MyBase.PerformDataBinding(oSourceData)
 ' Verify data exists.IfNot (oSourceData IsNothing) ThenDim oView As DataView = oSourceData
 Dim oTable As DataTable = oView.Table
 Dim oDS As DataSet = New DataSet()
 oDS.Tables.Add(oTable.Copy())
 'Create a Relation Between the ID Column and Parent ColumnIf oDS.Relations.Contains("SelfRefenceRelation") = FalseThen oDS.Relations.Add("SelfRefenceRelation", _
 oDS.Tables(0).Columns(DataFieldID), _
 oDS.Tables(0).Columns(DataFieldParentID))
 EndIf oTable.Dispose()
 oTable = Nothing ViewState("TreeData") = oDS
 LoadTreeView(oDS)
 oDS.Dispose()
 oDS = NothingEndIfEndSub

创建 DataSet 之后,调用 LoadTreeView 来填充 TreeView:

PrivateSub LoadTreeView(ByVal oDS As DataSet)
 Dim oTreeView As TreeView = New TreeView()
 Dim oDataRow As DataRow
 ForEach oDataRow In oDS.Tables(0).Rows
 'Find Root Node,A root node has ParentID NULLIf oDataRow.IsNull(DataFieldParentID) Then'Create Parent Node and add to treeDim oNode AsNew TreeNode()
 oNode.Text = oDataRow(DataTextField).ToString()
 oNode.Value = oDataRow(DataFieldID).ToString()
 oNode.NavigateUrl = oDataRow("NavigateURL").ToString()
 oTreeView.Nodes.Add(oNode)
 'Recursively Populate From root RecursivelyLoadTree(oDataRow, oNode)
 EndIfNext oDataRow
 Controls.Add(oTreeView)
 oDS.Dispose()
 oDS = NothingEndSub'LoadTreeView

首先识别 root 元素( ParentID = NULL ),然后添加到树,然后调用函数 RecursivelyLoadTree 递归创建子元素:

PrivateSub RecursivelyLoadTree(ByVal oDataRow As DataRow, _
 ByRef oNode As TreeNode)
 Dim oChildRow As DataRow
 'returns an array of DataRow objects representing the child view ForEach oChildRow In oDataRow.GetChildRows("SelfRefenceRelation")
 'Create child node and add to ParentDim oChildNode AsNew TreeNode()
 oChildNode.Text = oChildRow(DataTextField).ToString()
 oChildNode.Value = oChildRow(DataFieldID).ToString()
 oChildNode.NavigateUrl = _
 oChildRow("NavigateURL").ToString()
 oNode.ChildNodes.Add(oChildNode)
 'Repeat for each child RecursivelyLoadTree(oChildRow, oChildNode)
 Next oChildRowEndSub'RecursivelyLoadTree

使用代码

使用该控件的最简单方法是将它的绑定到数据源控件( DataSourceControl.aspx ):

<%@RegisterTagPrefix="CPArticles"Namespace="CPArticles"%><CPArticles:AutoBindingTreerunat="server"ID="TestCtrl"DataTextField="Text"DataFieldID="ID"DataFieldParentID="ParentID"DataSourceID="SqlDataSource1"/><asp:SqlDataSourceid="SqlDataSource1"runat="server"ConnectionString="<%$ ConnectionStrings:ConnectionString %>"SelectCommand="SELECT * FROM SelfReferenceTable"SelectCommandType="Text"/>

或者通过编程设置 DataSource 属性( DataBind.aspx ):

TestCtrl.DataFieldID = "ID"TestCtrl.DataFieldParentID = "ParentID"TestCtrl.DataTextField = "Text"TestCtrl.DataSource = oDs
TestCtrl.DataBind()

这两个示例和SQL脚本都在演示应用程序中。

历史记录

  • April 15,2007: 初始版本。

控制  AUTO  tab  BIN    REF  
相关文章