65.9K
CodeProject 正在变化。 阅读更多。
Home

从自引用表自动绑定 TreeView 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.57/5 (14投票s)

2007年4月16日

CPOL

2分钟阅读

viewsIcon

122124

downloadIcon

1462

支持从单个自引用表自动绑定的自定义 TreeView 控件

Screenshot - AutoBindingTreeView.gif

引言

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

背景

本文是我之前一篇文章的延续,展示了 TreeView 控件所缺乏的有用功能。之前的文章演示了如何应用 CSS 和向树节点添加自定义属性。在本文中,将讨论从自引用表自动绑定 TreeView 控件。

什么是自引用表?

自引用表包含一种关系,其中一列引用同一表中的另一列。例如

Self Referencing table

在上图中,父 ID 列引用 ID 列,这意味着父 ID 是形成分层数据的 ID。

自动绑定

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

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

  1. DataTextField:包含节点 Text 值的列的名称
  2. DataFieldID:包含 ID 值的列的名称
  3. DataFieldParentID:包含 ParentID 值的列的名称
Protected Overrides Sub PerformDataBinding(ByVal oSourceData As IEnumerable)
    MyBase.PerformDataBinding(oSourceData)

    ' Verify data exists.
    If Not (oSourceData Is Nothing) Then
    Dim 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 Column
        If oDS.Relations.Contains("SelfRefenceRelation") = False Then
        oDS.Relations.Add("SelfRefenceRelation", _
            oDS.Tables(0).Columns(DataFieldID), _
            oDS.Tables(0).Columns(DataFieldParentID))
        End If

        oTable.Dispose()
        oTable = Nothing

        ViewState("TreeData") = oDS
        LoadTreeView(oDS)

        oDS.Dispose()
        oDS = Nothing
    End If
        End Sub

创建 DataSet 后,将调用 LoadTreeView 来填充 Treeview

        
Private Sub LoadTreeView(ByVal oDS As DataSet)
    Dim oTreeView As TreeView = New TreeView()
    Dim oDataRow As DataRow
    For Each oDataRow In oDS.Tables(0).Rows
        'Find Root Node,A root node has ParentID NULL
        If oDataRow.IsNull(DataFieldParentID) Then
        'Create Parent Node and add to tree
        Dim oNode As New 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)
        End If
    Next oDataRow
    Controls.Add(oTreeView)
    oDS.Dispose()
    oDS = Nothing
End Sub 'LoadTreeView

首先,识别根元素 (ParentID = NULL),将其添加到树中,然后调用函数 RecursivelyLoadTree 以递归方式创建子元素

Private Sub RecursivelyLoadTree(ByVal oDataRow As DataRow, _
    ByRef oNode As TreeNode)
    Dim oChildRow As DataRow
    'returns an array of DataRow objects representing the child view 
    For Each oChildRow In oDataRow.GetChildRows("SelfRefenceRelation")
        'Create child node and add to Parent
        Dim oChildNode As New 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 oChildRow
End Sub 'RecursivelyLoadTree

使用代码

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

<%@ Register TagPrefix="CPArticles" Namespace="CPArticles"%>

<CPArticles:AutoBindingTree runat="server" ID="TestCtrl" 
    DataTextField="Text" 
    DataFieldID="ID" 
    DataFieldParentID="ParentID" 
    DataSourceID="SqlDataSource1" 
 />

  <asp:SqlDataSource id="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 脚本。

历史

  • 2007 年 4 月 15 日:首次发布。
© . All rights reserved.