ASP.NET 3.5核心编程学习笔记(18):数据绑定表达式
簡單數據綁定
數據綁定表達式是由<%...%>包裹的可執行代碼,以#號為前綴。它可以通過DataBoundLiteralControl類的實例以編程方式加以管理。
數據綁定表達式通常從數據源獲取數據,但并不是說它一定要從數據源獲取數據,只要返回綁定的數據,任何可執行代碼都是可以接受的。它僅在控件的DataBinding事件被觸發時才執行計算。
示例:<asp:label runat="server" Text='<%# DataTime.Now %>' />
如果要對表達式用引號,應選擇單引號。
我們在頁面中定義的數據綁定表達式會在DataBind被調用后計算。我們可以調用頁面對象的DataBind方法,也可以調用指定控件上的。如果調用頁面對象上的,便以遞歸方式調用定義在該頁面所有控件的DataBind方法,如果不調用DataBind,<%#...%>永遠不會被計算。
數據綁定表達式非常適合基于頁面中的其他控件更新當前控件的屬性,且完全以聲明方式編寫。 <asp:DropDownList ID="SelColors" runat="server" AutoPostBack="True"><asp:ListItem>Orange</asp:ListItem>
<asp:ListItem>Green</asp:ListItem>
<asp:ListItem>Red</asp:ListItem>
<asp:ListItem>Blue</asp:ListItem>
</asp:DropDownList>
<asp:Label runat="server" ID="lblColor" Text='<%# "<b>You Selected:</b>" + SelColors.SelectedValue %>' />
注意:<%#...%>中的表達式可以為方法、常量、屬性的結合體,只要最后的結果匹配綁定屬性的類型即可。表達式的計算需要回發,并調用DataBind方法。為此,我們將AutoPostBack設為true,同時還需要調用頁面或標簽的DataBind方法來觸發刷新過程。
protected void Page_Load(object sender, EventArgs e){
DataBind();
} 考慮下面的代碼: ForeColor='<%# "orange" %>'
ForeColor="orange"
以上代碼只有第二條語句能被正常解析。原因是,數據綁定表達式需要確保其返回值的類型與控件屬性的類型相匹配。但使用純文本常量字符串沒有問題,因為頁面解析器會識別該表達式。如果需要解析器會插入適當的類型轉換代碼。
數據綁定表達式的內部實現
如果Web頁面中出現數據綁定表達式會發生什么情況呢?考慮下面的代碼:
<asp:label runat="server" id="today" text='<%# DateTime.Now %>' /> 在頁面解析器處理.aspx源代碼時,會為每個服務器控件生成一個工廠方法,該工廠方法所做的工作只是將標簽的名稱映射到一個服務器控件的類,并以賦值方式將標簽中的屬性(attribute)轉換為對象的屬性(property)。此外,如果有數據綁定表達式,解析器還會添加當前控件的DataBinding事件的處理程序。以下代碼為該過程的執行結果: private Control __BuildControlToday(){
Label __ctrl = new Label();
this.today = __ctrl;
__ctrl.ID = "today";
__ctrl.DataBinding += new EventHandler(this.__DataBindToday);
return __ctrl;
} 該處理程序將數據綁定表達式的內容分步賦給相應屬性: public void __DataBindToday(object sender, EventArgs e)
{
Label target;
target = (Label)sender;
target.Text = Convert.ToString(DataTime.Now);
}
如果數據綁定表達式的值與期望的類型不匹配,則會出現編譯錯誤。如果期望的類型為字符串,解析器便會通過Convert.ToString方法執行標準的轉換。
DataBinder類
Eval方法是一種運算符,專用于數據綁定表達式,用于訪問綁定數據項的公共屬性。ASP.NET 2.0之前的頁面類中沒有Eval方法,如果在ASP.NET 1.x應用程序中直接使用,則會產生編譯錯誤。對于所有版本的ASP.NET來說,我們可以使用一個功能相同的方法,其名稱也為Eval,但來自另一個類--DataBinder。
通過Eval方法,我們能夠訪問綁定數據項的公共屬性。但需要澄清,這個上下文中的公共屬性是指什么?實現IEnumerable的類都可以綁定到控件上。具體的類包括DataTable(每個數據項在邏輯上對應一條記錄),也包括自定義集合(每個數據項對應于給定類的實例)。Eval方法會針對數據項的屬性集來查詢數據項對象。代表記錄的對象會返回所有字段的描述,而其他對象會返回各自的公共屬性集。
DataBinder類支持數據綁定表達式的生成和解析,其中的靜態方法Eval十分重要。對于運行時的對象,該方法會使用反射來解析并計算表達式。該方法的一般語法為:
<%# DataBinder.Eval(Container.DataItem, expression) %>Container.DataItem表達式用于引用一個對象,該對象中的表達式會被計算。expression一般為數據項對象中要訪問字段的名稱。它可以為包括索引或屬性名的表達式。DataItem屬性代表當前容器上下文中的對象。通常,容器一般為項目對象的當前實例。
更簡潔的Eval
原始的DataBinder.Eval語法在ASP.NET 2.0和更高版本中被簡化了,代碼可以這樣寫:
<%# Eval(expression) %> 而ASP.NET 1.x只能接受下述表達式: <%# DataBinder.Eval(Container.DataItem, expression) %>顯然,ASP.NET 2.0及更高版本也完全支持DataBinder類。
<%# ... %>分割符中出現的所有代碼都會被ASP.NET運行特殊處理。當頁面被編譯后,對Eval方法的調用會被插入到頁面的源代碼中,并單獨存在。下面的代碼揭示了其內部細節:
object o = Eval("lastname");string result = Convert.ToString(o);
調用的結果會被轉換為字符串,并賦給數據綁定控件,隨后,數據綁定文本會被插入到頁面控件樹中。
有了Eval方法,TemplateControl類得到了擴展,下面的偽碼揭示了該方法的內部原理:
protected object Eval(string expression){
if(Page == null)
throw new InvalidOperationException(...);
return DataBinder.Eval(Page.GetDataItem(), expression);
}
由此可見,Eval方法只是一個封閉器而已,它圍繞著DataBinder.Eval方法構建而成。DataBinder.Eval方法由當前容器的數據項調用。當前容器的數據在數據綁定操作執行之前是空的,這是Eval與DataBinder.Eval間的主要差異。
TemplateControl的Eval是一種數據綁定方法,僅用于數據綁定控件上下文中數據綁定操作期間。而DataBinder.Eval是一個完全自由的方法,可在任意位置使用。
默認數據項的獲取
在前面演示頁面Eval方法的代碼中用到了Page類的GetDataItem方法。這是什么呢?如前所述,簡化的語法用到了一個默認的Container.DataItem上下文對象。GetDataItem正是返回該對象的函數。
確切地講,GetDataItem是基于棧的調用機制的終點(這種機制會跟蹤頁面當前的綁定上下文)??丶渲械拿總€控件會在各自的DataBind方法被調用時壓入這個棧。DataBind方法返回時,相應控件會從棧中彈出。如果該棧為空,且試圖以編程方式調用Eval,GetDataItem會拋出無效操作異常??偠赃@,Eval的快捷方式只能在模板中使用,如果需要在其他位置訪問數據項屬性,必須借助于DataBinder.Eval,并顯式地指示數據項對象。
Bind方法
使用Eval方法的地方也可以使用Bind方法,二者的語法類似:
<asp:TextBox Runat="server" ID="TheNotes" Text='<%# Bind("notes") %>' />最大的不同在于Bind可以雙向執行--讀和寫。例如,在設置Text屬性時,Bind方法的行為與Eval一致。當Text被讀取時,Bind會將值存儲到集合中。ASP.NET中的數據綁定控件能自動獲取這些值,并將它們填充插入或編輯命令的參數列表,并對數據源執行這些命令。傳到Bind參數的名稱必須與命令中參數的名稱匹配。如,上述文本框會為@notes參數提供值。
用戶定義的動態表達式
數據綁定表達式不是真正的動態表達式,它們僅會在數據綁定調用上下文中被計算。
動態表達式與數據綁定的語法相似,它使用的是$前綴。動態表達式會在頁面編譯時計算,表達式的內容會被提取,轉換為代碼,并注入為頁面生成的代碼中。有幾個現有的表達式生成器:
或要以聲明方式將某個控件屬性綁定到表達式的值,可使用以下模式:
<%$ expression %>
確切的語法取決于每種表達式關聯的生成器的定義。但注意,頁面主體中不允許出現文本表達式。換言之,我們只能對控件的屬性應用表達式,而不能像下面這樣使用:
<h1><%$ AppSettings:AppVersionNumber %></h1> 我們應該將表達式封裝在服務器控件中,最簡單的是使用Literal控件,代碼如下: <h1><asp:Literal runat="server" Text="<%$ Resource:Resource, AppWelcome %>" /></h1><hr/><h1><asp:Literal runat="server" Text="<%$ AppSettings:AppVersionNumber %>" /></h1>
<hr/>
顯然,App_GlobalResource中要包含AppWelcome字符串資源,Web.Config文件中也要有AppVersionNumber設置。
ConnectionStrings表達式對于數據源控件非常有用,它避免了在aspx文件中對連接字符串硬編碼。
開發者通過編寫從ExpressionBuilder派生的類,可以定義其他的表達式。為使其能夠識別并被正確處理,需要在web.config文件中注冊自定義的表達式生成器。
轉載于:https://www.cnblogs.com/free722/archive/2011/04/18/2019985.html
總結
以上是生活随笔為你收集整理的ASP.NET 3.5核心编程学习笔记(18):数据绑定表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Win32窗体控件方法与消息
- 下一篇: 凌乱
