本文闡述如何為 TreeView 控件新增資料繫結功能,屬於 Microsoft Windows 控件開發示例系列之一。建議搭配相關概述文章閱讀。
在可能情況下,應優先使用現成控件;因 Microsoft Windows Forms 內建控件包含大量編碼與測試成果,若從頭開始無疑是巨大浪費。基於此,本例將繼承現有 Windows Forms 控件 TreeView 並進行自訂。下載該 TreeView 控件代碼時,還將獲得附加的控件開發示例,以及示範如何與其他資料繫結控件搭配使用的增強 TreeView 應用程式。
對 Windows 開發人員而言,為 TreeView 新增資料繫結是常見需求,但因 TreeView 與 ListBox、DataGrid 等控件存在主要差異——TreeView 顯示階層式資料——基本控件目前尚不支援此功能。給定一個資料表,在 ListBox 或 DataGrid 中顯示資訊很直觀,但利用 TreeView 的階層特性呈現相同資料則不那麼直觀。我曾嘗試多種方法在 TreeView 中顯示資料,最常用的是依某些欄位將表中資料分組,如圖 1 所示。

圖 1:在 TreeView 中顯示資料
本例將建立一個 TreeView 控件,可傳遞平面資料集(如圖 2 所示),並輕鬆生成圖 1 的結果。

圖 2:包含建立圖 1 樹狀結構所需所有資訊的平面結果集
在編碼前,我為新控件構思了一個能處理特定資料集的設計,並期望適用於許多類似情境。新增一個足以使用大多數平面資料建立階層結構的分組集合,在集合中為每一層階層指定分組欄位、顯示欄位與值欄位(任一或所有欄位均可相同)。為將圖 2 資料轉換成圖 1 TreeView,新控件要求定義兩個分組層級 Publisher 與 Title,並將 pub_id 定義為 Publisher 組的分組欄位,title_id 為 Title 組的分組欄位。除分組欄位外,還需為每個組指定顯示與值欄位,以決定相應組節點顯示的文字以及唯一識別特定組的值。遇到此類資料時,請使用 pub_name/pub_id 與 title/title_id 作為這兩組的顯示/值欄位。作者資訊將成為樹的葉節點(分組階層結構末端節點),同樣需指定 ID (au_id) 與顯示 (au_lname) 欄位。
構建自訂控件時,在編碼前確定程式設計師對控件的使用方式有助於提升控件使用效率。此情況下,我希望程式設計師(在給定上述資料與所需結果下)能用幾行代碼完成分組:
With DbTreeControl
.ValueMember = "au_id"
.DisplayMember = "au_lname"
.DataSource = myDataTable.DefaultView
.AddGroup("Publisher", "pub_id", "pub_name", "pub_id")
.AddGroup("Title", "title_id", "title", "title_id")
End With
註:這並非最終代碼,但相差不遠。開發過程中我意識到需將與 TreeView 關聯之 ImageList 圖像索引與每個分組層級關聯,因此必須向 AddGroup 方法額外新增一個參數。
為真正建構該樹,我將瀏覽資料並尋找指定為每個分組之分組值的變更,在必要時建立新分組節點,並為每個資料項建立一個葉節點。因存在分組節點,總節點數將大於資料來源項目數,但基礎資料中每個項目有且僅有一個葉節點。

圖 3:分組節點與葉節點
葉節點與分組節點的區別(如圖 3 所示)對本文餘下部分至關重要。我決定將這兩類節點區別對待,為每類節點分別建立自訂節點類別,並根據所選節點類型引發不同事件。