本文件已封存並已停止維護。

逐步解說:顯示 TreeView 控制項中的階層式資料

ASP.NET TreeView 控制項設計用於以階層式結構向使用者顯示資料。使用者可開啟個別節點,這些節點因此可包含子節點。TreeView 控制項適合用於顯示 XML 資料,但可用於以階層架構表示的任何資料。這個逐步解說會示範使用 TreeView 控制項的基本概念,以及顯示階層式資料的各種方式。

逐步解說將說明的工作包括:

  • 使用 TreeView 控制項顯示 XML 資料。

  • 自訂 TreeView 控制項的顯示。

  • TreeView 控制項中顯示關聯資料庫資料表中的資料錄。

若要完成這個逐步解說,您必須要有:

  • Microsoft Visual Web Developer (Visual Studio)。

  • Microsoft Data Access Components (MDAC) 2.7 (含) 以後版本。

    如果使用的是 Microsoft Windows XP 或 Windows Server 2003,您就會已經有了 MDAC 2.7。不過,如果您使用的是 Microsoft Windows 2000,可能需要升級電腦中所安裝的 MDAC。如需詳細資訊,請參閱 MSDN Library 中的<Microsoft Data Access Components (MDAC) Installation>。

  • 存取 SQL Server Northwind 資料庫。如需下載並安裝 SQL Server 範例 Northwind 資料庫的詳細資訊,請參閱 Microsoft SQL Server 網站上的安裝範例資料庫

    Note注意事項

    如果您需要如何登入執行 SQL Server 之電腦的相關資訊,請聯繫伺服器管理員。

  • 對 Northwind 資料庫具有存取權限之 SQL Server 帳戶的使用者名稱和密碼 (如果 SQL Server 資料庫與 Web 伺服器不是位於同一電腦上)。

依照下列步驟建立新的網站和 Web 網頁。

若要建立檔案系統網站

  1. 開啟 Visual Web Developer。

  2. 在 [檔案] 功能表上按一下 [新增],然後按一下 [網站]。如果您是使用 Visual Web Developer Express,請在 [檔案] 功能表中按一下 [新網站]。

    [新網站] 對話方塊隨即出現。

  3. 請在 [Visual Studio 安裝的範本] 下方,按一下 [ASP.NET 網站]。

  4. 在 [位置] 方塊中,選取 [檔案系統],並輸入您想要用來保存網站頁面的資料夾名稱。

    例如,輸入資料夾名稱 C:\WebSites\HierarchicalData

  5. 在 [語言] 清單中,請按一下您想要操作的程式語言。

  6. 按一下 [確定]。

    Visual Web Developer 會建立資料夾和命名為 Default.aspx 的新頁面。

藉由遵循這些步驟建立新的 XML 檔。

若要建立 XML 檔

  1. 在 [方案總管] 中,以滑鼠右鍵按一下網站,再按 [加入新項目]。

  2. 在 [加入新項目] 對話方塊的 [標準範本] 下,按一下 [XML 檔]。

  3. 在 [名稱] 方塊中,輸入 Bookstore.xml,然後按一下 [加入]。

    Visual Web Developer 會建立新的 Bookstore.xml 檔,並開啟程式碼編輯器。

  4. 複製下列 XML 資料,然後將這些資料貼到 Bookstore.xml 檔中,覆寫檔案中原有的內容。

    <?xml version="1.0" standalone="yes"?>
    <bookstore>
      <genre name="fiction">
        <book ISBN="10-000000-001">
          <title>The Iliad and The Odyssey</title>
          <price>12.95</price>
          <comments>
            <userComment rating="4">
               Best translation I've read.
            </userComment>
            <userComment rating="2">
               I like other versions better.
            </userComment>
          </comments>
        </book>
        <book ISBN="10-000000-999">
          <title>Anthology of World Literature</title>
          <price>24.95</price>
          <comments>
            <userComment rating="3">
              Needs more modern literature.
            </userComment>
            <userComment rating="4">
              Excellent overview of world literature.
            </userComment>
          </comments>
        </book>
      </genre>
      <genre name="nonfiction">
        <book ISBN="11-000000-002">
          <title>Computer Dictionary</title>
          <price>24.95</price>
          <comments>
            <userComment rating="3">A valuable resource.</userComment>
          </comments>
        </book>
        <book ISBN="11-000000-003">
          <title>Cooking on a Budget</title>
          <price>23.95</price>
          <comments>
            <userComment rating="4">Delicious!</userComment>
          </comments>
        </book>
      </genre>
    </bookstore>
    

    XML 檔包含可從線上 bookstore 取得之書籍的資訊。

  5. 儲存 Bookstore.xml 檔案,然後將其關閉。

在本節中,您將使用 TreeView 控制項顯示 XML 資料。若要開始,您可以顯示 XML 資訊,而無需任何特殊組態。

若要顯示 XML 資料

  1. 開啟 Default.aspx 網頁,然後切換至 [設計] 檢視。

  2. 在 [工具箱] 中,將 [TreeView] 控制項從 [巡覽] 群組拖曳至網頁。

  3. 以滑鼠右鍵按一下 [TreeView] 控制項,再按 [顯示智慧標籤]。

  4. 在 [TreeView 工作] 功能表的 [選擇資料來源] 下拉式清單中,選取 [新增資料來源]。[資料來源組態精靈] 隨即出現。

  5. 在 [應用程式要從何處取得資料] 視窗中,選取 [XML 檔]。保留資料來源的預設 ID。按一下 [確定]。

  6. 在 [設定資料來源] 對話方塊的 [資料檔案] 方塊中,輸入 ~/Bookstore.xml,然後按一下 [確定]。

您現在可以測試網頁。

若要測試網頁

  1. 按 CTRL+F5 執行頁面。

  2. 摺疊後展開控制項中的節點。

    根據預設,節點只會顯示 Bookstore.xml 檔中項目的標記 (Tag) 名稱。

您可以藉由建立自訂繫結 (該繫結可讓您指定要向每一個節點顯示 XML 檔的何種資訊),自訂在 TreeView 控制項中顯示的資訊。

若要建立自訂繫結

  1. 請在 Default.aspx 網頁上,以滑鼠右鍵按一下 [TreeView] 控制項,再按 [顯示智慧標籤]。

  2. 在 [TreeView 工作] 功能表上,按一下 [編輯 TreeNode Databindings]。

    [TreeView DataBindings 編輯器] 對話方塊隨即出現。

  3. 清除 [自動產生資料繫結] 核取方塊,因為您將定義資料繫結 (Data Binding)。

  4. 按一下 [加入] 建立新繫結,然後在 [資料繫結屬性] 下,將 [DataMember] 設為 [bookstore],並將 [文字] 設為 [書籍資訊]。

    因為 [Bookstore] 節點是 .xml 檔中的最上層節點,且只在 [TreeView] 控制項中出現一次,所以您要設定繫結以顯示靜態 (Static) 值。

  5. 按一下 [加入] 建立第二個繫結,然後在 [資料繫結屬性] 下,將 [DataMember] 設為 [genre],並將 [TextField] 設為 [name]。

    如此會指定節點將讀取 .xml 檔中的 <genre> 項目,並將其 name 屬性 (Attribute) 指派給 TextField 屬性 (Property)。

  6. 按一下 [加入] 建立書籍的第三個繫結,然後在 [資料繫結屬性] 下,將 [DataMember] 設為 [book],並將 [TextField] 設為 [ISBN]。

  7. 按一下 [確定]。

您現在可以測試網頁。

若要測試網頁

  • 按 CTRL+F5 執行頁面。

    此時,TreeView 控制項會顯示與您定義之繫結對應的三個層級。這三個層級是標記為 [書籍資訊] 的根節點、類型群組和 ISBN 詳細資訊。

您可以為 XML 檔中的任何項目建立資料繫結,但您只可繫結至項目的屬性、內部文字、項目名稱或項目的值。您無法繫結至任何巢狀項目。若要顯示巢狀項目中的值,請建立那些項目的個別繫結。另一個方法是使用 XSLT 轉換 XML 檔,以便將內部項目轉換成屬性。如需詳細資訊和範例,請參閱 System.Web.UI.WebControls.XmlDataSource.TransformFile 屬性。

TreeView 控制項可顯示任何型別的階層式資料,即使資料階層架構是邏輯的 (例如在資料庫中) 而不是實體的 (例如在 XML 檔中)。在本節中,您將使用 TreeView 控制項顯示 Northwind 資料庫之關聯表格中的資料。

若要開始,您要建立執行具有 Northwind 資料庫的 SQL Server 之電腦的連接。

若要建立對 SQL Server 的連接

  1. 在 [伺服器總管] 中,以滑鼠右鍵按一下 [資料連接],再按一下 [加入資料連接]。如果您是使用 Visual Web Developer Express,請使用 [資料庫總管]。

    [加入連接] 對話方塊就會出現。

    • 如果 [資料來源] 清單未顯示 [Microsoft SQL Server (SqlClient)],請按一下 [變更],然後在 [變更資料來源] 對話方塊中選取 [Microsoft SQL Server]。

    • 如果出現 [選擇資料來源] 頁面,請在 [資料來源] 清單中選取您將使用的資料來源類型。在此逐步解說中,資料來源型別為 Microsoft SQL Server。在 [資料提供者] 清單中,按一下 [.NET Framework Data Provider for SQL Server],然後按一下 [繼續]。

    Note注意事項

    如果在 Visual Web Developer 中看不到 [伺服器總管] 索引標籤,請在 [檢視] 功能表中按一下 [伺服器總管]。如果看不到 [資料庫總管] 索引標籤,請在 [檢視] 功能表中按一下 [資料庫總管]。

  2. 在 [加入資料連接] 方塊中,於 [伺服器名稱] 方塊中輸入伺服器名稱。

  3. 在 [登入伺服器] 區段中,請選取適用於存取執行中之 SQL Server 資料庫的選項 (整合式安全性或特定 ID 和密碼),且如果有必要,請輸入使用者名稱和密碼。

  4. 選取 [儲存我的密碼] 核取方塊。

    Note注意事項

    在實際執行應用程式中,請不要使用 [儲存我的密碼],因為這會將使用者名稱和密碼內嵌在應用程式檔案中。

  5. 請在 [選取或輸入資料庫名稱] 底下,輸入 Northwind

  6. 按一下 [測試連接],然後在您確定它有正常運作時,按一下 [確定]。

    您的新連接已建立在 [伺服器總管] (或 [資料庫總管]) 中的 [資料連接] 下。

設定 TreeView 控制項顯示資料庫資料

在本節中,您將用資料動態填入 (Populate) 節點。第一層級的節點表示主要資料 (此處為分類)。當使用者按一下節點時,會藉由對擷取分類之產品的資料庫進行查詢,建立該分類的子節點。若要擷取資料,您可以使用資料來源控制項。然而,在這個逐步解說中,您將以程式的方式建立和執行查詢。

若要開始,請建立新網頁和新的 TreeView 控制項。

若要建立新網頁和 TreeView 控制項

  1. 將名為 TreeViewDynamic.aspx 的 ASP.NET Web 網頁 (Web Form 網頁) 加入您的網站。

  2. 開啟 TreeViewDynamic.aspx 網頁、切換至 [設計] 檢視,然後在 Toolbox 中,將 Label 控制項從 [標準] 群組中拖曳至網頁,並將其命名為 labelStatus

    labelStatus 控制項只用於錯誤報告。

  3. 在 [工具箱] 中,將 [TreeView] 控制項從 [巡覽] 群組拖曳至網頁。

  4. 以滑鼠右鍵按一下 [TreeView] 控制項,再按 [屬性],然後將 [MaxDataBindDepth] 設為 2

  5. 以滑鼠右鍵按一下 [TreeView] 控制項,再按 [顯示智慧工作],然後在 [TreeView 工作] 功能表上按 [編輯節點]。

  6. 在 [TreeView 節點編輯器] 對話方塊中,按一下標記為 [加入根節點] 的圖示,然後在 [屬性] 下,將 [文字] 設為 Product List,並將 [PopulateOnDemand] 設為 true

  7. 按一下 [確定]。

    您會建立樹狀結構的最上層節點,其中只包含靜態文字。

若要設定 Web.config 檔

  1. 在 [工具箱] 中,將 SqlDataSource 控制項從 [資料] 群組拖曳至網頁。

  2. 選取 [SqlDataSource] 控制項,然後按一下 [顯示智慧標籤]。

  3. 在 [SqlDataSource 工作] 功能表上,按一下 [設定資料來源]。

    [設定資料來源 - SqlDataSource1] 精靈會顯示一個頁面,讓您在其中選擇連接。

  4. 在 [您的應用程式應該使用哪個資料連接來連接資料庫?] 方塊中,輸入您在<建立 SQL Server 的連接>中所建立的連接,然後按一下 [下一步]。

    精靈會顯示一個頁面,您可以在該頁面中選擇將連接字串 (Connection String) 儲存在組態檔中。在組態檔中儲存連接字串有兩個優點:

    • 這麼做比將它儲存在頁面裡來得安全。

    • 您可以在多個頁面中使用相同的連接字串。

  5. 選取 [是,將這個連接儲存為] 核取方塊,然後按 [下一步]。

    此精靈會顯示一個頁面,您可以在其中指定要從資料庫擷取哪些資料。

  6. 在 [指定資料表或檢視的資料行] 的 [名稱] 方塊中,按一下 [分類]。

  7. 在 [資料行] 下方,選取 [CategoryID] 和 [CategoryName] 方塊。

  8. 按一下 [下一步]。

  9. 按一下 [完成]。

    您稍後將在這個逐步解說稍後定義的 RunQuery 方法中使用在 Web.config 檔中建立的連接字串。您將不會使用 SqlDataSource 控制項。

現在,您將加入程式碼,以在使用者按一下節點時填入控制項的子節點。若要動態加入節點,您要建立 TreeNodePopulate 事件的事件處理常式。

若要建立事件處理常式

  1. 以滑鼠右鍵按一下 [TreeView] 控制項,然後在 [屬性] 中按 [事件] 圖示。

  2. 按兩下 TreeNodePopulate 事件的方塊。

    將 Visual Web Developer 切換至 [原始碼] 檢視。

  3. 將下列以粗體顯示的程式碼加入至處理常式:

    Protected Sub TreeView1_TreeNodePopulate(ByVal sender As Object, _
    ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _
    Handles TreeView1.TreeNodePopulate
        If e.Node.ChildNodes.Count = 0 Then
            Select Case e.Node.Depth
                Case 0
                    PopulateCategories(e.Node)
                Case 1
                    PopulateProducts(e.Node)
            End Select
        End If
    End Sub
    

    protected void TreeView1_TreeNodePopulate(
        object sender, TreeNodeEventArgs e)
    {
        if (e.Node.ChildNodes.Count == 0)
        {
            switch (e.Node.Depth)
            {
                case 0:
                    PopulateCategories(e.Node);
                    break;
                case 1:
                    PopulateProducts(e.Node);
                    break;
            }
        }
    }
    

    當使用者按一下以開啟節點時,會呼叫此程式碼。因為您想要在樹狀結構的不同層級顯示不同的資料,所以必須判斷使用者按一下的節點深度,然後於該層級適當地填入節點。在這個逐步解說中,如果使用者按一下根節點 (深度 0),則會呼叫 PopulateCategories 方法。如果使用者按一下分類名稱 (深度 1),則會呼叫 PopulateProducts 方法。上述方法會在下一節中顯示。

    TreeNodeEventArgs 物件會以程式的方式存取目前節點。若要填入節點,您要將項目加入節點。在範例程式碼中,會將節點傳遞至加入子節點的方法。

從資料庫讀取節點資料

在每一個節點中顯示的資訊都來自資料庫。您必須撰寫程式碼,以執行資料庫查詢、讀取資料錄,並為每一個資料錄建立節點。這個逐步解說會假設您是在使用 SQL Server Northwind 範例資料庫,因此您必須從 System.Data.SqlClient 命名空間使用 ADO.NET 物件。

對於節點的第一層級 (層級 0),您將顯示所有可用分類的清單。您所建立的程式碼會呼叫您稍後將會在逐步解說中建立的 RunQuery 方法。

若要加入所有分類的節點

  1. 切換至原始碼檢視。

  2. 如果您是在使用單一檔案網頁,則會將下列指示詞加入字碼頁 (Code Page) 的頂端。

    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    

    匯入命名空間會讓撰寫您所需要的程式碼更加容易。

  3. 如果您是在使用程式碼後置 (Code-Behind) 網頁,請切換至程式碼後置網頁 (TreeViewDynamic.aspx.vb 或 TreeViewDynamic.aspx.cs),並將下列數行程式碼加入類別宣告外之程式碼檔的頂端。

    Imports System.Data
    Imports System.Data.SqlClient
    

    using System.Data;
    using System.Data.SqlClient;
    
  4. 確保網頁仍處於 [原始碼] 檢視中。

  5. 將下列方法加入網頁程式碼。

    Sub PopulateCategories(ByVal node As TreeNode)
        Dim sqlQuery As New SqlCommand( _
            "Select CategoryName, CategoryID From Categories")
        Dim ResultSet As DataSet
        ResultSet = RunQuery(sqlQuery)
        If ResultSet.Tables.Count > 0 Then
            Dim row As DataRow
            For Each row In ResultSet.Tables(0).Rows
                Dim NewNode As TreeNode = New _
                    TreeNode(row("CategoryName").ToString(), _
                    row("CategoryID").ToString())
                NewNode.PopulateOnDemand = True
                NewNode.SelectAction = TreeNodeSelectAction.Expand
                node.ChildNodes.Add(NewNode)
            Next
        End If
    End Sub
    

    void PopulateCategories(TreeNode node)
    {
        SqlCommand sqlQuery = new SqlCommand(
            "Select CategoryName, CategoryID From Categories");
        DataSet resultSet;
        resultSet = RunQuery(sqlQuery);
        if (resultSet.Tables.Count > 0)
        {
            foreach (DataRow row in resultSet.Tables[0].Rows)
            {
                TreeNode NewNode = new
                    TreeNode(row["CategoryName"].ToString(),
                    row["CategoryID"].ToString());
                NewNode.PopulateOnDemand = true;
                NewNode.SelectAction = TreeNodeSelectAction.Expand;
                node.ChildNodes.Add(NewNode);
            }
        }
    }
    

    該程式碼會建立封裝查詢文字的 SqlCommand 物件。它會將物件傳遞至會執行資料庫查詢並傳回 DataSet 物件的方法 (您將會撰寫該方法)。然後,該程式碼會在 DataSet 物件的資料錄中執行迴圈 (Loop),並為每一個資料錄建立新節點,同時以資料庫資訊設定節點的文字和值。然後,該程式碼會將每一個節點的 PopulateOnDemand 屬性設為 true,以便在按一下節點時,節點會引發其 TreeNodePopulate 事件。設定 SelectAction 屬性,讓節點根據預設處於展開狀態。

節點的第二層級將顯示每一個分類的產品。因此,填入產品節點會需要參數型查詢,以便您可以為目前分類擷取產品,並適當地填入子節點。

若要加入產品的節點

  • 將下列方法加入網頁程式碼。

    Sub PopulateProducts(ByVal node As TreeNode)
        Dim sqlQuery As New SqlCommand
        sqlQuery.CommandText = "Select ProductName From Products " & _
            " Where CategoryID = @categoryid"
        sqlQuery.Parameters.Add("@categoryid", SqlDbType.Int).Value = _
            node.Value
        Dim ResultSet As DataSet = RunQuery(sqlQuery)
        If ResultSet.Tables.Count > 0 Then
            Dim row As DataRow
            For Each row In ResultSet.Tables(0).Rows
                Dim NewNode As TreeNode = New _
                    TreeNode(row("ProductName").ToString())
                NewNode.PopulateOnDemand = False
                NewNode.SelectAction = TreeNodeSelectAction.None
                node.ChildNodes.Add(NewNode)
            Next
        End If
    End Sub
    

    void PopulateProducts(TreeNode node)
    {
        SqlCommand sqlQuery = new SqlCommand();
        sqlQuery.CommandText = "Select ProductName From Products " +
            " Where CategoryID = @categoryid";
        sqlQuery.Parameters.Add("@categoryid", SqlDbType.Int).Value =
            node.Value;
        DataSet ResultSet = RunQuery(sqlQuery);
        if (ResultSet.Tables.Count > 0)
        {
            foreach (DataRow row in ResultSet.Tables[0].Rows)
            {
                TreeNode NewNode = new
                    TreeNode(row["ProductName"].ToString());
                NewNode.PopulateOnDemand = false;
                NewNode.SelectAction = TreeNodeSelectAction.None;
                node.ChildNodes.Add(NewNode);
            }
        }
    }
    

    此程式碼與用於填入分類節點的程式碼類似。其中一點不同之處在於,設定 SqlCommand 物件時,會使用在執行階段以使用者已按一下的節點 (也就是已選取的分類) 之值設定的參數。另一點區別是,會將 PopulateOnDemand 屬性設為 false。如此在顯示產品節點時不顯示展開按鈕。這是十分必要的,因為這些產品下並沒有其他節點。

最後一步是建立執行查詢和傳回資料集的方法。

若要執行查詢

  • 將下列副程式加入網頁。

    Function RunQuery(ByVal sqlQuery As SqlCommand) As DataSet
        Dim connectionString As String
        connectionString = _
            ConfigurationManager.ConnectionStrings _
            ("NorthwindConnectionString").ConnectionString
        Dim dbConnection As New SqlConnection
        dbConnection.ConnectionString = connectionString
        Dim dbAdapter As New SqlDataAdapter
        dbAdapter.SelectCommand = sqlQuery
        sqlQuery.Connection = dbConnection
        Dim resultsDataSet As DataSet = New DataSet
        Try
            dbAdapter.Fill(resultsDataSet)
        Catch ex As Exception
            labelStatus.Text = "Unable to connect to SQL Server."
        End Try
        Return resultsDataSet
    End Function
    

    private DataSet RunQuery(SqlCommand sqlQuery)
    {
        string connectionString =
            ConfigurationManager.ConnectionStrings
            ["NorthwindConnectionString"].ConnectionString;
        SqlConnection DBConnection =
            new SqlConnection(connectionString);
        SqlDataAdapter dbAdapter = new SqlDataAdapter();
        dbAdapter.SelectCommand = sqlQuery;
        sqlQuery.Connection = DBConnection;
        DataSet resultsDataSet = new DataSet();
        try
        {
            dbAdapter.Fill(resultsDataSet);
        }
        catch
        {
            labelStatus.Text = "Unable to connect to SQL Server.";
        }
        return resultsDataSet;
    }
    

    此程式碼會基於傳遞至它的 SqlCommand 物件建立資料配接器 (Adapter)。然後,它會用該配接器建立和填入資料集。

您現在可以測試網頁。

若要測試網頁

  1. 按 CTRL+F5 執行頁面。

    TreeView 控制項會顯示分類和產品清單。

  2. 按一下分類,確認它會摺疊和展開以為每一個分類顯示產品清單。

這個逐步解說同時使用階層式 XML 資料和關聯資料庫填入 TreeView 控制項。您可以使用 TreeView 控制項,將網站巡覽資訊和 XML 資料用做表格式 (清單) 資料。

顯示: