如果回到Visual Basic的時代,資料繫結(data binding)是一項被遺棄的笨拙編程技術。DAO過分簡單和速度緩慢的控制項讓資料繫結得了個壞名聲,許多有經驗的開發人員根本就不是用它。當時很普遍的看法是:“真正的程式員不吃蛋奶餅,而他們肯定也不用資料繫結!”
但是有了.NET之後,許多東西都發生了改變,其中一個變化是在快速應用程式開發中用於資料來源的繫結控制項具有了高效率。事實上,.NET讓整個資料繫結的概念超越了原有簡單地把控制項附加到資料表格上的概念。這種能力對ASP.NET的開發人員尤其有用,因為這就更多地把他們同應用程式資料訪問層的反覆無常隔絕起來。
資料繫結101:DataSet
用最簡單的方式來看,資料繫結牽涉了將ASP.NET的Web控制項,例如說ListBox,附加到包含一些資料庫資料的DataSet上。ListBox.DataSource屬性讓你指定控制項要綁定的DataSet,而DataBind方法會真正地用資料來填充控制項。由於DataSet可以包含多個欄位,所以帶有單個資料列的控制項(ListBox、DropDownList等等)都會公開DataTextField和DataKeyField屬性,這樣你就能夠分別指定控制項將要以文本形式顯示的欄位名或者用於值的欄位名。
Listing A包含了一個簡單的例子,它將ListBox綁定到Northwind樣本資料庫的Categories表格上。在建立了DataSet之後,我用DataSource屬性將它綁定到ListBox1。然後把DataTextField屬性設定為CategoryName,後者是ListBox1應該顯示的欄位(它會被用作SelectedItem.Text),把DataKeyField屬性設定為CategoryId,這樣ListBox1就會把它用作鍵。(它會被返回為SelectedItem.Value.)。
資料繫結201:數組和集合
好,綁定到DataSet是小孩的把戲。但是如果你所要的資料不在資料庫裡,那又會怎麼樣呢?如果你想讓使用者能夠從對象數列裡進行選擇,那又會怎麼樣呢?當然,你能夠手動建立包含有資料的DataSet,但是這有點像要蓋一座大樓,而你所需要的其實是一個工具棚。如果你只需要直接綁定到數組上,這是不是會很好?
事實的確如此,你可以直接綁定到參照類型變數的數組,這正如Listing B。在本文裡,我有一個類——DataClass,它公開了兩個屬性,Description和ID。我可以建立一個DataClass對象的數組,並將它綁定到ListBox1,這和我在Listing A裡對DataSet所做的一樣:把DataTextField設定為Description(描述),把DataKeyField設定為ID。
ASP.NET使用即時的Reflection API來檢查數組裡的對象並找到正確的屬性,它然後會把它們載入到ListBox1的ListItemCollection裡。要注意,ASP.NET會專門去尋找property的成員——公開變數或者函數方法在這裡都不起作用。
Listing C說明集合約樣能夠很好的工作,這其實並不會讓你以外,因為我敢肯定到現在這個時候,你應該已經非常瞭解.NET是如何使用IEnumerable and IEnumerator interfaces to iterate over collections的。如果你碰巧不知道我在說什麼,試著看看將ListBox1綁定到CollectionClass的Listing D,它通過實現Ienumerable和Ienumerator來獲得類似集合的迭代能力。
資料繫結301:DataGrid
對DataGrid和相關控制項的資料繫結也是類似的,只不過你要處理的可能是控制項裡一個以上的列——否則,為什麼要用DataGrid呢?DataGrid預設的綁定行為相當智能:所有的列(在使用DataSet的情況下)或者公用屬性(在對其他對象的情況下)會被顯示出來。所以只設定DataSource屬性會給你一個函數資料繫結方格。
當然在有些情況下,你不想用DataGrid來為自己建立列。你可以取消預設的列自動產生的行為,並把AutoGenerateColumns屬性設定為偽(false),這樣就能夠控制DataGrid的列的產生和綁定。然後你就可以使用Visual Studio .NET 的列屬性編輯器為格建立列,如圖 A所示,或者通過為DataGrid所應該包含的每個列建立一個System.Web.UI.WebControls.BoundColumn執行個體來實現這一點.
圖A
Visual Studio .NET提供了一個優秀的列屬性編輯器
Listing E重新編寫了Listing C裡集合綁定的例子,以此來操作DataGrid。我首先關閉了DataGrid1裡列自動產生的特性,然後建立了一個新的BoundColumn對象。通過使用DataField屬性,我把列對象綁定到DataClass的Description屬性上,再把它添加到DataGrid1的列集合裡。
畢業典禮!
資料繫結不僅僅是快速應用程式開發的一個重要方法,它還有助於將你資料結構的細節對應用程式的展示層隱藏起來。但是通過同樣的機制來綁定資料庫和對象資料,微軟讓在應用程式裡使用資料繫結控制項更加實用了。