Author: Walkdan (walkdan(at)gmail.com)
ASP.NET 2.0 的Eval()簡化了掉了ASP 1.1 Container.DataItem,例如:
<%# (Container.DataItem as DataRowView)["ProductName"].ToString( ) %>
簡化為:(去掉了型別指定ASP 1.1, Eval透過反射實現,本文不再闡述)
<%# DataBinder.Eval(Container.DataItem, "ProductName").ToString() %>
又簡化為(ASP 2.0):
<%# Eval("ProductName") %>
Eval()是TemplateControl:Page 的方法
TemplateControl.Eval()可以自動計算出Container, 機制就是從一個dataBindingContext:Stack堆疊來取得。
1. 建立DataItem Container 堆疊:
在Control.DataBind()中,建立,這樣可以確保子控制項的DataItem Container始終在棧頂。
public class Control
{
protected virtual void DataBind(bool raiseOnDataBinding)
{
bool foundDataItem = false;
if (this.IsBindingContainer)
{
object o = DataBinder.GetDataItem(this, out foundDataItem);
if (foundDataItem)
Page.PushDataItemContext(o); <-- 將DataItem壓入堆疊
}
try
{
if (raiseOnDataBinding)
OnDataBinding(EventArgs.Empty);
DataBindChildren(); <-- 綁定子控制項
}
finally
{
if (foundDataItem)
Page.PopDataItemContext(); <-- 將DataItem彈出堆疊
}
}
}
2. 取得DataItem Container
public class Page
{
public object GetDataItem()
{
…
return this._dataBindingContext.Peek(); <-- 讀取堆疊頂部的DataItem Container,就是正在綁定的DataItem Container
}
}
3. TemplateContro.Eval()
public class TemplateControl
{
protected string Eval (string expression, string format)
{
return DataBinder.Eval (Page.GetDataItem(), expression, format);
}
}