<%# (Container.DataItem as DataRowView)["ProductName"].ToString() %><%# DataBinder.Eval(Container.DataItem, "ProductName").ToString() %><%# Eval("ProductName") %> —— 完全隱藏 Container.DataItem。Eval 是 TemplateControl 的方法,內部通過 Page.GetDataItem() 獲取當前綁定項。關鍵在於 Control.DataBind() 中維護的一個 DataItem 堆棧:
protected virtual void DataBind(bool raiseOnDataBinding)
{
bool foundDataItem = false;
if (this.IsBindingContainer)
{
object o = DataBinder.GetDataItem(this, out foundDataItem);
if (foundDataItem) Page.PushDataItemContext(o); // 壓入堆棧
}
try
{
if (raiseOnDataBinding) OnDataBinding(EventArgs.Empty);
DataBindChildren(); // 遞歸綁定子控件,子控件的 DataItem 會在棧頂
}
finally
{
if (foundDataItem) Page.PopDataItemContext(); // 彈出堆棧
}
}
public object GetDataItem()
{
return this._dataBindingContext.Peek(); // 讀取堆棧頂部的 DataItem
}
protected string Eval(string expression, string format)
{
return DataBinder.Eval(Page.GetDataItem(), expression, format);
}
Eval 看似簡化了語法,實則將 Container.DataItem 的獲取過程「黑盒化」。開發者不再顯式看到數據源上下文,反而可能對綁定機制理解模糊。建議:
Eval 只能在數據綁定上下文中工作。ItemDataBound 事件或模板中的顯式綁定表達式,保持可讀性與可調試性。