1、Eval取出来的数据时只读的,而Bind是可更新的数据。2、Eval通常用来需要对数据进行格式化成字符串,因而和Bind方法比,性能会有所下降。3、在运行时,Eval调用DataBinder对象的Eval方法,同时引用命名容器的滚樱轮当前数据项。命名容器通常是包含完整记录的数据绑定控件的最小组成部分,如 GridView 控件中的一行。因此,只能对数据绑定控件的模板内的绑定使用 Eval 方法。具体内容可以参考MSDN中大信关于DataBinder.Eval()方法的描述。注意:当前容器的数据项:Container.DataItem4、Bind()方法的运用,主要应用场景:GridView等可编辑控件的更新操作上。当单击Update按钮时,使用 Bind 语法绑定的每个控件属性值都会被提取出来,并传递给数据源控颂局件以执行更新操作。
Eval(
"
")和Bind(
"
") 这两种一个单向绑定,一个双向绑定
bind是双向绑定,但需数据源可更改才能用
ASP.NET
2.0改善了模板中的数据绑定操作,把v1.x中的数据绑定语法DataBinder.Eval(Container.DataItem,
fieldname)简化为Eval(fieldname)。Eval方法与DataBinder.Eval一样可以接受一个可选的格式化字符串参数。缩短的Eval语法与DataBinder.Eval的不同点在于,Eval会根据最近的容器对象(例如DataListItem)的DataItem属性来自动地解析字段,而DataBinder.Eval需要使用参数来指定容器。由于这个原因,Eval只能在数据绑定控件的模板中使用,而不能用于Page(页面)层。当然,ASP.NET
2.0页面中仍然支持DataBinder.Eval,你可以在不支持简化的Eval语法的环境中使用它。
下面的例子演示了如何使用新的简化的Eval数森耐据绑定语法绑定到DataList数据项模板(ItemTemplate)中的Image、Label和HyperLink控件。
<asp:DataList
ID=
"DataList1
"
RepeatColumns=
"5
"
Width=
"600
"
runat=
"server
"
DataSourceID=
"ObjectDataSource1
">
<ItemTemplate>
<asp:HyperLink
ID=
"HyperLink1
"
runat=
"server
"
NavigateUrl=
'<%#
Eval(
"PhotoID
",
"PhotoFormViewPlain.aspx?ID={0}
")
%>
'>
<asp:Image
ID=
"Image1
"
Runat=
"server
"
ImageUrl=
'<%#
Eval(
"FileName
",
"images/thumbs/{0}
")
%>
'
/></asp:HyperLink>
<asp:Label
ID=
"CaptionLabel
"
runat=
"server
"
Text=
'<%#
Eval(
"Caption
")
%>
'
/>
</ItemTemplate>
</asp:DataList><br
/>
<asp:ObjectDataSource
ID=
"ObjectDataSource1
"
runat=
"server
"
TypeName=
"DataComponentTableAdapters.PhotosTableAdapter
"
SelectMethod=
"GetPhotosForAlbum
">
数据绑定也可袜如以作为控件的主题定义(theme
definition)的一部分,这样我们就可以通过改告春启变主题来随意地改变模板化控件的布局和外观。但是Theme(主题)模板中只能使用Eval(或者后面讨论的Bind)。绑定到任意的用户代码是被禁止的。
--------关注----------
常见绑定格式,不过他们的性能有区别。
<%#
DataBinder.Eval(Container.DataItem,
"[n]")
%>
<%#
DataBinder.Eval(Container.DataItem,
"ColumnName")
%>
<%#
DataBinder.Eval(Container.DataItem,
"ColumnName",
null)
%>
<%#
DataBinder.Eval(Container,
"DataItem.ColumnName",
null)
%>
<%#
((DataRowView)Container.DataItem)["ColumnName"]
%>
<%#
((DataRowView)Container.DataItem).Row["ColumnName"]
%>
<%#
((DataRowView)Container.DataItem)["adtitle"]
%>
<%#
((DataRowView)Container.DataItem)[n]
%>
<%#
((DbDataRecord)Container.DataItem)[0]
%>
<%#
(((自定义类型)Container.DataItem)).属性.ToString()
%>(如果属性为字符串类型就不用ToString()了)
上面这三个性能最好。
//显示二位小数
//<%#
DataBinder.Eval(Container.DataItem,
"UnitPrice",
"${0:F2}")
%>
//{0:G}代表显示True或False
//
//
Height="12"
Border="0"
runat="server"
//
AlternateText='<%#
DataBinder.Eval(Container.DataItem,
"Discontinued",
"{0:G}")
%>'
//
ImageUrl='<%#
DataBinder.Eval(Container.DataItem,
"Discontinued",
"~/images/{0:G}.gif")
%>'
/>
//
//转换类型
((string)DataBinder.Eval(Container,
"DataItem.P_SHIP_TIME_SBM8")).Substring(4,4)
{0:d}
日期只显示年月日
{0:yyyy-mm-dd}
按格式显示年月日
{0:c}
货币样式
---------------------------------------------------------
在本章前面,我们在模板上下文中遇到过<%#...%>表达式以及Eval方法。Eval方法是一种定制运算符,在数据绑定表达式用来方法所绑定的数据项上的公共属性。前文所用的Eval方法是一个ASP.NET
2.0才支持的特征,如果在ASP.NET
1.x应用程序中使用,则会产生一个编译错误。对于ASP.NET的所有版本,我们可以使用一个在功能上相当的方法,该方法也称为Eval,但是来自另一个类——DataBinder。
重要提示:
通过Eval方法(尽管它来自DataBinder或Page类),可以访问所绑定的数据项上的公共属性。让我澄清一下公共属性在该上下文中指什么,以及为什么我坚持把它们叫做属性。任何一个实现了IEnumerable接口的类都可以绑定到一个控件。实际的类列表当然包括DataTable(其中一个数据项在逻辑上对应于表记录),但是它还包括定制集合(其中一个数据项对应于给定类的一个实例。)Eval方法最终会查询该数据项对象以得到它的属性集。表示一个表记录的对象将返回它的列描述符;其他对象将返回它们的公共属性集。
DataBinder类支持数据绑定表达式的生成和解析。它的静态重载方法Eval特别重要。该方法使用反射机制来解析和计算一个运行时对象的表达式。Eval方法的客户包括RAD工具,诸如Microsoft
Visual
Studio
.NET设计器和Web控件,它们以声明的方式调用该方法用动态改变的值填充这些属性。
1.
Eval方法
DataBinder.Eval方法的语法如下:
<%#
DataBinder.Eval(Container.DataItem,
expression)
%>
上述代码片断中省略了第3个可选参数。该参数是一个字符串,包含所绑定值的格式选择。Container.DataItem表达式引用对该表达式进行计算的对象。该表达式通常是一个字符串,表示数据项对象上要访问的字段的名称。它可以是一个包括索引和属性名的表达式。DataItem属性表示当前容器上下文中的对象。容器通常即将生成的该数据项对象(例如,DataGridItem对象)的当前实例。
前面所示的代码通常重复出现,而且以相同的形式。只有表达式和格式字符串在页与页之间会有所变化。
2.
更简洁的Eval
DataBinder.Eval的原始语法在ASP.NET
2.0中可以被简化,这一点我们在前面的Repeater示例中已经看到。在ASP.NET
2.0中,只要在ASP.NET
1.x中接受如下表达式的地方:
<%#
DataBinder.Eval(Container.DataItem,
expression)
%>
就可以使用:
<%#
Eval(expression)
%>
不用说,ASP.NET
2.0也是完全支持DataBinder对象的。
在<%#
...
%>界定符内出现的任何代码,都会得到ASP.NET运行库的特殊处理。让我们简单分析一下该代码会发生什么。编译该页面时,Eval调用作为一个独立的调用插入该页面的源代码中。如下代码说明了会发生什么:
object
o
=
Eval("lastname");
string
result
=
Convert.ToString(o);
该调用的结果被转换为一个字符串,并付给一个数据绑定的文字控件——DataBoundLiteralControl类的一个实例。然而把数据绑定的文字插入该页的控件树中。
在ASP.NET
2.0中,TemplateControl类(Page的父类)实际上新增了一个名为Eval的受保护的(但不是虚拟的)方法。如下伪代码说明该方法的工作机制:
protected
object
Eval(string
expression)
{
if
(Page
==
null)
throw
new
InvalidOperationException(…);
return
DataBinder.Eval(Page.GetDataItem(),
expression);
}
正如我们可以看到的,Eval是建立在DataBinder.Eval方法之上的一个简单包装。DataBinder.Eval方法使用当前容器的数据项调用。非常明显,当前容器的数据在数据绑定操作之外为null——即,在调用DataBind之后的调用栈中。这一事实引起了Eval和DataBinder.Eval之间的一个关键区别。
重要提示:
TemplateControl的Eval是一个数据绑定方法,在一个数据绑定操作中只能在一个数据绑定控件的上下文中使用。相反,DataBinder.Eval是一个完全成熟的方法,可以在程序中的任何地方使用。我们通常在定制的数据绑定控件的实现中使用它。我将在本书的姐妹篇《Programming
Microsoft
ASP.NET
2.0
Applications:
Advanced
Topics
》中介绍它。
3.
获得默认的数据项
前面给出的说明页面的Eval方法的行为的伪码,展示了Page类的GetDataItem方法。它是什么?如前所述,这一简化语法采用一个默认的Container.DataItem上下文对象。GetDataItem只不过是返回该对象的函数。
更精确地讲,GetDataItem是跟踪页面的当前绑定上下文的基于栈的机制的终点。该控件树中的每个控件在调用各DataBind方法时压入该栈中。DataBind方法返回时,控件从该栈中弹出。如果栈是空的,并且企图以编程的方式调用Eval方法,则GetDataItem抛出一个无效的操作异常。总之,我们只能在模板中使用Eval简化操作;如果需要在代码中的任何其他地方访问一个数据项的属性,则利用DataBinder.Eval方法,并显式地指出数据项对象。
提示
如前所述,通常只有在定制的数据绑定控件的代码中才需要直接调用DataBinder.Eval方法。(我在Programming
Microsoft
ASP.NET
2.0
Applications:
Advanced
Topics中介绍了定制控件。)然而,如果发生这种情况,可能需要通过调用DataBinder.GetPropertyValue方法来保存几个内部调用和CPU周期。最终,这完全是由DataBinder.Eval完成的。