Author: Walkdan (walkdan(at)gmail.com)
ASP.NET 2.0's Eval() simplifies ASP 1.1 Container.DataItem, such as:
<%# (Container.DataItem as DataRowView)["ProductName"].ToString( ) %>
is simplified to: (ASP 1.1 removes the type specification, Eval is implemented through reflection, which will not be explained in this article)
<%# DataBinder.Eval(Container.DataItem, "ProductName").ToString() %>
is simplified to (ASP 2.0):
<%# Eval("ProductName") %>
Eval() is a method of TemplateControl:Page
TemplateControl.Eval() can automatically calculate the Container, and the mechanism is to obtain it from a dataBindingContext:Stack stack.
1. Create the DataItem Container stack:
In Control.DataBind(), establish this to ensure that the DataItem Container of the child control is always on the top of the stack.
public classControl
{
protected virtual void DataBind(bool raiseOnDataBinding)
{
bool foundDataItem = false;
if (this.IsBindingContainer)
{
object o = DataBinder.GetDataItem(this, out foundDataItem);
if(foundDataItem)
Page.PushDataItemContext(o); <-- Push DataItem onto the stack
}
try
{
if (raiseOnDataBinding)
OnDataBinding(EventArgs.Empty);
DataBindChildren(); <-- bind child controls
}
finally
{
if(foundDataItem)
Page.PopDataItemContext(); <-- Pop the DataItem from the stack
}
}
}
2. Get DataItem Container
public class Page
{
public object GetDataItem()
{
...
return this._dataBindingContext.Peek(); <-- Read the DataItem Container at the top of the stack, which is the DataItem Container being bound.
}
}
3. TemplateContro.Eval()
public class TemplateControl
{
protected string Eval (string expression, string format)
{
return DataBinder.Eval (Page.GetDataItem(), expression, format);
}
}