ASP.NET 使用宣告式語法 <%# 運算式 %> 進行資料繫結,**僅在呼叫 DataBind() 時運算**,區別於舊版 ASP 的 <%= %> (頁面處理階段即運算)。
| 繫結目標 | 語法範例 | 說明 |
|---|---|---|
| 單一屬性/變數 | Customer: <%# custID %> | 顯示字串、數值等純量 |
| 集合 (DataSource) | <asp:ListBox DataSource='<%# myArray %>' /> | 陣列、ArrayList、DataView 等 IEnumerable |
| 運算式 | Contact: <%# customer.FirstName + " " + customer.LastName %> | 任意合法運算式,結果 ToString() 輸出 |
| 方法回傳值 | Balance: <%# GetBalance(custID) %> | 呼叫頁面/控制項方法,回傳值輸出 |
繫結運算式結果為 Object,若目標屬性需特定型別 (如 DataSource 需 IEnumerable),必須明確轉型:
' 整數轉字串顯示
Records: <%# count.ToString() %>
' 陣列繫結至 ListBox
<asp:ListBox DataSource='<%# CType(myArray, IEnumerable) %>' />
Page.DataBind() 或 DataBind():觸發頁面上**所有**繫結運算式運算。Control.DataBind():遞迴觸發該控制項及其所有子控制項的繫結。Page_Load 中呼叫:If Not IsPostBack Then DataBind()。<script runat="server">
Protected ReadOnly Property CustID() As String
Get : Return "ALFKI" : End Get
End Property
Protected ReadOnly Property OrderCount() As Integer
Get : Return 11 : End Get
End Property
Protected Sub Page_Load(sender As Object, e As EventArgs)
Me.DataBind() ' 觸發所有 <%# %> 運算
End Sub
</script>
<form runat="server">
Customer: <b><%# CustID %></b><br/>
Open Orders: <b><%# OrderCount %></b>
</form>
屬性/變數必須在 DataBind() 前初始化完成。
<asp:TextBox ID="txtKeyword" runat="server" />
<asp:GridView ID="gvResults" runat="server"
DataSource='<%# SearchProducts(txtKeyword.Text) %>' />
來源控制項 (txtKeyword) 必須在命名容器內可存取。
Dim list As New ArrayList()
list.Add("Apple")
list.Add("Banana")
list.Add("Cherry")
' 頁面或控制項屬性
Protected ReadOnly Property Fruits() As ArrayList
Get : Return list : End Get
End Property
' ASPX
<asp:Repeater DataSource='<%# Fruits %>' runat="server">
<ItemTemplate><%# Container.DataItem %><br/></ItemTemplate>
</asp:Repeater>
Protected ReadOnly Property ProductsView() As DataView
Get
Dim dt As DataTable = GetProductsDataTable()
Return dt.DefaultView
End Get
End Property
' 支援排序、篩選
ProductsView.Sort = "Price DESC"
ProductsView.RowFilter = "CategoryID = 5"
在資料繫結控制項模板 (如 GridView、FormView、Repeater) 中:
<%# Eval("FieldName") %>:單向繫結 (唯讀),相當於 DataBinder.Eval(Container.DataItem, "FieldName")。<%# Eval("FieldName", "Format") %>:支援格式化,如 <%# Eval("Price", "{0:C}") %>。<%# Bind("FieldName") %>:雙向繫結 (可編輯),用於編輯模板 (EditItemTemplate)。<asp:FormView ID="fvProduct" runat="server" DataSourceID="odsProduct"
DataKeyNames="ProductID" DefaultMode="ReadOnly">
<ItemTemplate>
名稱: <%# Eval("ProductName") %><br/>
價格: <%# Eval("UnitPrice", "{0:C}") %><br/>
庫存: <%# Eval("UnitsInStock") %>
<asp:LinkButton CommandName="Edit" Text="編輯" runat="server" />
</ItemTemplate>
<EditItemTemplate>
名稱: <asp:TextBox ID="txtName" Text='<%# Bind("ProductName") %>' runat="server" /><br/>
價格: <asp:TextBox ID="txtPrice" Text='<%# Bind("UnitPrice") %>' runat="server" /><br/>
<asp:LinkButton CommandName="Update" Text="更新" runat="server" />
<asp:LinkButton CommandName="Cancel" Text="取消" runat="server" />
</EditItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="odsProduct" runat="server"
TypeName="ProductBLL" SelectMethod="GetProduct"
UpdateMethod="UpdateProduct"
DataObjectTypeName="ProductEntity">
</asp:ObjectDataSource>
DataBind()、或在 IsPostBack 時未重新繫結。Eval("Field") 遇到 DBNull,用 <%# Eval("Field") ?? "N/A" %> (C#) 或 <%# If(Eval("Field") Is Nothing, "N/A", Eval("Field")) %> (VB)。{0:C} 需數值型別,字串型別會拋出例外。Bind 僅限編輯模板,且資料來源需支援更新 (ObjectDataSource/SqlDataSource 設定 UpdateMethod/UpdateCommand)。ASP.NET 2.0 資料繫結透過 <%# %> 宣告式語法、DataBind() 統一觸發機制、Eval/Bind 簡化模板繫結,提供強大且彈性的資料呈現能力。掌握繫結目標類型 (屬性、集合、運算式、方法)、型別轉換、巢狀控制項繫結與雙向編輯模式,能讓開發者以最少程式碼實現複雜的資料驅動 UI。