ASP.NET2.0高級數據處理之數據綁定
在前面的"模板中的數據綁定"部分中我們論述過,ASP.NET包含了一種宣告式的數據綁定語法,用于在數據綁定模板中把數據源字段與控件的屬性相關聯。你也可以在代碼中使用<%# ... >語法來進行任意值的數據綁定,例如頁面和控件屬性、集合、表達式,甚至于方法調用的返回結果。為了強制計算數據綁定的值,你必須在包含數據綁定語法的頁面或控件上調用DataBind方法。下面的表格顯示了ASP.NET中的數據綁定語法的一些例子。
盡管上面的語法與ASP的Response.Write便捷語法(<%= %>)看起來類似,但是它們的行為卻決然不同。ASP Response.Write便捷語法在頁面處理的時候計算值,而ASP.NET數據綁定語法只在DataBind方法被調用的時候才計算值。
DataBind是頁面和所有務器控件的一個方法。當你調用父控件的DataBind的時候,它會依次調用所有子控件的DataBind方法。例如,DataList1.DataBind()就會調用DataList模板中的所有控件的DataBind方法。調用頁面的DataBind方法--Page.DataBind() 或簡單地調用 DataBind()--會引發頁面上所有的數據綁定表達式的計算操作。通常只在頁面的Page_Load事件中調用DataBind方法,如下面的例子所示。
在.aspx頁面的任何宣告式片斷中,你都可以使用綁定語法,并為它的估值指定運行時所期望的數據類型。上面例子中的簡單屬性、表達式和方法在被計算的時候會向用戶顯示文本內容。在這種情況下,數據綁定表達式的值是String類型的。在上面的集合例子中,數據綁定語法的值的類型是ListBox的DataSource屬性。你會發現在綁定表達式中強制轉換值的類型對于生成期望的結果是必要的。例如,如果count是一個整數:
ASP.NET數據綁定語法支持公共變量、頁面的屬性和頁面中其它控件的屬性的綁定。下面的例子演示了如何綁定到公共變量和頁面的簡單屬性。請注意,在DataBind()被調用之前,這些值都已經初始化過了。
下面的例子演示如何綁定到另一個控件的屬性:
列表類型的服務器控件(例如DropDownList、ListBox和HTMLSelect)把集合作為數據源。下面的例子演示如何綁定到通用語言運行時集合類型。這些控件只能綁定到支持Ienumerable、Icollection或IlistSource接口的集合。更為常見的是,它可以綁定到ArrayList、Hashtable、DataView和DataReader。下面的例子演示了如何綁定到ArrayList。
下面的例子演示了如何綁定到DataView。請注意DataView類是在System.Data名字空間中定義的。
下面的例子演示了如何綁定到Hashtable。
通常情況下,你可能希望綁定到頁面或控件之前先處理數據。下面的例子演示了如何綁定到表達式和方法的返回值。
ASP.NET頁面框架組件提供了一個靜態的方法,它估算延遲綁定(late-bound)的數據綁定表達式并可以選擇把其結果格式化為字符串。在這種情況下,DataBinder.Eval很方便,因為它消除了開發者把估值轉會為期望的數據類型所必須執行的很多顯式轉化工作。當模板化列表中有數據綁定控件的時候,它特別有用處,因為在那種情況下,通常數據行和數據字段都必須轉換。
看看下面的例子,它需要把整數顯示為貨幣字符串。在標準的ASP.NET數據綁定語法中,你必須首先轉換數據行的類型以檢索數據字段IntegerValue。接著把它作為參數傳遞給String.Format方法。
這個語法很復雜并且不容易記住。與此形成對照的是,DataBinder.Eval是一個簡單的方法,它只有三個參數:數據項的命名容器(naming container)、數據字段名稱和格式化字符串。在模板化的控件(例如FormView、 GridView、DetailsView、DataList或Repeater)中,命名容器都是Container.DataItem。頁面(Page)是另一種命名容器,也可以用于DataBinder.Eval。前面我們提到,ASP.NET 2.0為DataBinder.Eval提供了一個新的簡化的語法(Eval),你可以在數據綁定的控件模板中使用它來自動解析Container.DataItem。
格式化字符串參數是可選的。如果省略了這個參數,DataBinder.Eval會返回Object類型值,如下所示:
我們要重點注意的是,與標準的數據綁定語法相比,DataBinder.Eval會明顯地影響性能,這是因為它使用了延遲綁定的反射(reflection)。請明智地使用DataBinder.Eval,特別是在不需要格式化字符串的情況下。
| 單個屬性 | Customer: <%# custID %> |
| 集合 Orders | <asp:ListBox id="List1" datasource='<%# myArray %>' runat="server"> |
| 表達式 Contact | <%# ( customer.FirstName + " " + customer.LastName ) %> |
| 方法的返回值 | Outstanding Balance: <%# GetBalance(custID) %> |
盡管上面的語法與ASP的Response.Write便捷語法(<%= %>)看起來類似,但是它們的行為卻決然不同。ASP Response.Write便捷語法在頁面處理的時候計算值,而ASP.NET數據綁定語法只在DataBind方法被調用的時候才計算值。
DataBind是頁面和所有務器控件的一個方法。當你調用父控件的DataBind的時候,它會依次調用所有子控件的DataBind方法。例如,DataList1.DataBind()就會調用DataList模板中的所有控件的DataBind方法。調用頁面的DataBind方法--Page.DataBind() 或簡單地調用 DataBind()--會引發頁面上所有的數據綁定表達式的計算操作。通常只在頁面的Page_Load事件中調用DataBind方法,如下面的例子所示。
在.aspx頁面的任何宣告式片斷中,你都可以使用綁定語法,并為它的估值指定運行時所期望的數據類型。上面例子中的簡單屬性、表達式和方法在被計算的時候會向用戶顯示文本內容。在這種情況下,數據綁定表達式的值是String類型的。在上面的集合例子中,數據綁定語法的值的類型是ListBox的DataSource屬性。你會發現在綁定表達式中強制轉換值的類型對于生成期望的結果是必要的。例如,如果count是一個整數:
| Number of Records: <%# count.ToString() %> |
ASP.NET數據綁定語法支持公共變量、頁面的屬性和頁面中其它控件的屬性的綁定。下面的例子演示了如何綁定到公共變量和頁面的簡單屬性。請注意,在DataBind()被調用之前,這些值都已經初始化過了。
| <script language="VB" runat="server"> Sub Page_Load(sender As Object, e As EventArgs) Page.DataBind End Sub ReadOnly Property custID() As String Get Return "ALFKI" End Get End Property ReadOnly Property orderCount() As Integer Get Return 11 End Get End Property </script> <form action="DataBind1_vb.aspx" runat="server"> Customer: <b><%# custID %></b><br /> Open Orders: <b><%# orderCount %></b> </form> |
下面的例子演示如何綁定到另一個控件的屬性:
| <asp:DropDownList id="StateList" runat="server"> <asp:ListItem>CA</asp:ListItem> …… </asp:DropDownList> <asp:button ID="Button1" Text="Submit" OnClick="SubmitBtn_Click" runat="server"/> Selected State: <asp:label ID="Label1" text='<%# StateList.SelectedItem.Text %>' runat="server"/> |
列表類型的服務器控件(例如DropDownList、ListBox和HTMLSelect)把集合作為數據源。下面的例子演示如何綁定到通用語言運行時集合類型。這些控件只能綁定到支持Ienumerable、Icollection或IlistSource接口的集合。更為常見的是,它可以綁定到ArrayList、Hashtable、DataView和DataReader。下面的例子演示了如何綁定到ArrayList。
| Sub Page_Load(sender As Object, e As EventArgs) If Not IsPostBack Then Dim values as ArrayList= new ArrayList() values.Add ("IN") values.Add ("KS") values.Add ("MD") values.Add ("MI") values.Add ("OR") values.Add ("TN") DropDown1.DataSource = values DropDown1.DataBind End If End Sub |
下面的例子演示了如何綁定到DataView。請注意DataView類是在System.Data名字空間中定義的。
| Sub Page_Load(sender As Object, e As EventArgs) If Not IsPostBack Then Dim dt As DataTable Dim dr As DataRow Dim i As Integer '建立DataTable dt = New DataTable dt.Columns.Add(New DataColumn("IntegerValue", GetType(Integer))) dt.Columns.Add(New DataColumn("StringValue", GetType(String))) dt.Columns.Add(New DataColumn("DateTimeValue", GetType(DateTime))) dt.Columns.Add(New DataColumn("BooleanValue", GetType(Boolean))) '填充一些數據 For i = 1 To 9 dr = dt.NewRow() dr(0) = i dr(1) = "Item " + i.ToString() dr(2) = DateTime.Now.ToShortTimeString If (i Mod 2 <> 0) Then dr(3) = True Else dr(3) = False End If '把數據行添加到表 dt.Rows.Add(dr) Next GridView1.DataSource = New DataView(dt) GridView1.DataBind() End If End Sub |
下面的例子演示了如何綁定到Hashtable。
| Sub Page_Load(sender As Object, e As EventArgs) If Not IsPostBack Then Dim h As Hashtable = new Hashtable() h.Add ("key1", "value1") h.Add ("key2", "value2") h.Add ("key3", "value3") MyDataList.DataSource = h MyDataList.DataBind End If End Sub |
通常情況下,你可能希望綁定到頁面或控件之前先處理數據。下面的例子演示了如何綁定到表達式和方法的返回值。
| Sub Page_Load(sender As Object, e As EventArgs) If Not IsPostBack Then Dim values as ArrayList= new ArrayList() values.Add (0) values.Add (1) values.Add (2) values.Add (3) values.Add (4) values.Add (5) values.Add (6) DataList1.DataSource = values DataList1.DataBind End If End Sub Function EvenOrOdd(number As Integer) As String If (number Mod 2 <> 0) Then Return "Odd" Else Return "Even" End If End Function <asp:DataList id="DataList1" ……> <ItemTemplate> Number Value: <%# Container.DataItem %> Even/Odd: <%# EvenOrOdd(Container.DataItem) %> </ItemTemplate> </asp:DataList> |
ASP.NET頁面框架組件提供了一個靜態的方法,它估算延遲綁定(late-bound)的數據綁定表達式并可以選擇把其結果格式化為字符串。在這種情況下,DataBinder.Eval很方便,因為它消除了開發者把估值轉會為期望的數據類型所必須執行的很多顯式轉化工作。當模板化列表中有數據綁定控件的時候,它特別有用處,因為在那種情況下,通常數據行和數據字段都必須轉換。
看看下面的例子,它需要把整數顯示為貨幣字符串。在標準的ASP.NET數據綁定語法中,你必須首先轉換數據行的類型以檢索數據字段IntegerValue。接著把它作為參數傳遞給String.Format方法。
| <%# String.Format("{0:c}", (CType(Container.DataItem, DataRowView)("IntegerValue"))) %> |
這個語法很復雜并且不容易記住。與此形成對照的是,DataBinder.Eval是一個簡單的方法,它只有三個參數:數據項的命名容器(naming container)、數據字段名稱和格式化字符串。在模板化的控件(例如FormView、 GridView、DetailsView、DataList或Repeater)中,命名容器都是Container.DataItem。頁面(Page)是另一種命名容器,也可以用于DataBinder.Eval。前面我們提到,ASP.NET 2.0為DataBinder.Eval提供了一個新的簡化的語法(Eval),你可以在數據綁定的控件模板中使用它來自動解析Container.DataItem。
| <%# DataBinder.Eval(Container.DataItem, "IntegerValue", "{0:c}") %> <%# Eval("IntegerValue", "{0:c}") %> |
格式化字符串參數是可選的。如果省略了這個參數,DataBinder.Eval會返回Object類型值,如下所示:
| <%# CType(DataBinder.Eval(Container.DataItem, "BoolValue"), Boolean) %> |
我們要重點注意的是,與標準的數據綁定語法相比,DataBinder.Eval會明顯地影響性能,這是因為它使用了延遲綁定的反射(reflection)。請明智地使用DataBinder.Eval,特別是在不需要格式化字符串的情況下。