浅谈.NET中的数据绑定表达式(一)(转)

今天谈下.NET中的数据绑定表达式。
数据绑定表达式
必须包含在<%#和%>字符之间。格式如下:

< tagprefix:tagname  property ='<%#  data-binding expression % > ' runat="server" />
或者如下:
<% # data - binding expression  %>
ASP.NET 支持分层数据绑定模型,数据绑定表达式使用 EvalBind 方法将数据绑定到控件,并将更改提交回数据库。
Eval 方法是静态单向(只读)方法,所以Eval 函数用于单向(只读)绑定,该方法采用数据字段的值作为参数并将其作为字符串返回。
Bind 方法支持读/写功能,所以Bind 函数用于双向(可更新)绑定。该方法可以检索数据绑定控件的值并将任何更改提交回数据库。
XPath 方法支持对XML类型的数据源提供支持。

数据绑定表达式都可以出现在页面的哪个位置呢?

一,可以将数据绑定表达式包含在服务器控件或者普通的html元素的开始标记中属性名/属性值对的值侧。例如:
< asp:TextBox  ID ="TextBox1"  runat ="server"  Text ='<%#数据绑定表达式% > ' > </ asp:TextBox >< br  />
注意条款:此时数据的绑顶表达式可以是一个变量,也可以是一个带返回值的C#或者VB.NET方
,还可以是某个控件的某个属性的值,也可以是C#或者VB.NET对象的某个字段或者属性的值
等。当然也可以直接就是一个字符串,例如"hello"。

如果此时的数据绑定表达式是Eval("数据库中某个表的某个字段")等,那么必须把TextBox1放在某
个循环显示的控件的模板中才正确,否则会提示:Eval()、XPath() 和 Bind() 这类数据绑定方
法只能在数据绑定控件的上下文中使用。
其实就是想让你把TextBox1放在像Repeater,DataList,
GridView这样的控件的模板中。

二,数据绑定绑定表达式包含在在页面中的任何位置。例如
< form  id ="form1"  runat ="server" >
    
< div >
     
<% # Eval ( " 数据绑定表达式1 " ) %>   
     
<% # Eval ( " 数据绑定表达式2 " ) %>         
    
</ div >  
</ form >

同样遵循"一"的注意条款。
如果此时的数据绑定表达式是Eval("数据库中某个表的某个字段")等,那么必须把 <%#Eval("数
据绑定表达式1
")
%>   <%#Eval("数据绑定表达式2")%>  放在像Repeater,DataList,
GridView这样的控件的模板中。


三,可以将数据绑定表达式包含在Javascript代码中,从而实现在Javascript中调用C#或者
VB.NET的方法。例如:
Deafult2.aspx:

<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeFile = " Default2.aspx.cs "  Inherits = " Default2 "   %>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml"   >
< head  runat ="server" >
    
< title > 无标题页 </ title >
    
< script  language  ="javascript"  type ="text/javascript" >
    
function  GetStr()
    {
       
var  a; 
       a 
=   ''
       a
= ' <%#CSharpToJavascript()%> '           // 调用c#的方法
       alert(a);
    }
    
</ script >     
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
    
< div >
        
< input  id ="Button1"  type ="button"  value ="Javascript调用c#的方法!"  onclick ="GetStr()"  /</div >  
    
</ form >
</ body >
</ html >

Default2.cs:
using  System;
using  System.Data;
using  System.Configuration;
using  System.Collections;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Web.UI.HtmlControls;

public   partial   class  Default2 : System.Web.UI.Page
{
    
protected   void  Page_Load( object  sender, EventArgs e)
    {
        Page.DataBind();
// 方法有返回值的要先绑定,才能实现Javascript调用c#的方法!
    }
    
public   string  CSharpToJavascript()
    {
        
return   " Javascript调用c#的方法! " ;
    }
}

数据绑定表达式都可以是什么类型呢?
1,可以是一个变量
例如:<asp:Label ID="Label1" runat="server" Text="<%#变量名%>"></asp:Label>
2,可以是服务器控件的属性值
例如: <asp:Label ID="Label1" runat="server" Text="<%#TextBox2.Text %>"></asp:Label>
3,可以是一个数组等集合对象
例如把一个数组绑定到列表控件,例如ListBox等,或者Repeater,DataList,GridView这样的控
件等,
此时只需要把属性DataSource='<%# 数组名%>' 。
4,可以是一个表达式
例如:Person是一个对象,Name和City是它的2个属性,则数据绑定表达式可以这样写:

<%#(Person.Name + " " + Person.City)%>。
5,可以是一个方法
例如:<%#GetUserName()%>。GetUserName()是一个已经定义的C#方法,一般要求有
返回值。
6,可以是用Eval,DateBind.Eval取得的数据表的字段,这个是最常见的了,不再举例。


注意:如果数据绑定表达式作为属性的值,只要数据绑定表达式中没有出现双引号,那么<%#数据绑定表达式%>的最外层
用双引号或者单引号都可以。如果数据绑定表达式中出现双引号,则<%#数据绑定表达式%>的最外层最好要用单引号。

与数据库有关而且绑定到DataView,DataTable,DataSet 等数据源的数据绑定表达式都有那些?

1,<%#DataBind.Eval(Container.DataItem,"字段名")%>
      <%#DataBind.Eval(Container.DataItem,"字段名","{0:c}") %>
     还有2种不常用的:
      <%# DataBinder.Eval(Container,"DataItem.字段名")%> 
      <%# DataBinder.Eval(Container,"DataItem.字段名",{0:c})%> 
      Container.DataItem相当于数据库中某个表或者视图中的一行记录,而一行可以有很多
列。
      最后一个参数和 String.Format的形式一样。例如c代表货币,p代表百分号,d代表短日期
格式显示,f代表浮点数现实,f3代表小数点后三为,一次类推。

         使用三目运算符?:的例子:
 <%# DataBinder.Eval(Container.DataItem, "字段名").ToString().Trim().Length>
16?DataBinder.Eval(Container.DataItem, "字段名
").ToString().Trim().Substring(0,16):DataBinder.Eval(Container.DataItem, "字段名").ToString().Trim() %>


2,<%#Eval("字段名")%>
     <%#Eval("字段名","{0:c}")%>
     .NET 2.0新出现的一个方法。和DataBind.Eval()等价。

     最后一个参数和 String.Format的形式一样。例如c代表货币,p代表百分号,d代表短日期格
式显示,f代表浮点数现实,f3代表小数点后三位,一次类推。

     使用三目运算符的例子:
<%#(Eval("性别")).ToString() =="True"?"男":"女"%>

 性别字段类型为:是/否(Access),bit(sql server)
      使用方法调用的例子:
  <%# GetUserPhoto(Eval("PhotoPath")) %>    
     GetUserPhoto()的定义:
string  GetUserPhoto( object  photoPath)
{
  
if  (photoPath  ==  DBNull.Value) <% #((DataRowView)Container.DataItem)[ " 字段名 " %>
绑定到DataView,DataTable,DataSet
  {
      
return   " <img src='Images/none.gif'> " ;
  }
  
else
  {
    
return   " <img src='Upload/ "   + photoPath.ToString()  +   " '> " ;
  }
}

3, <%#((DataRowView)Container.DataItem)["字段名"] %>
      <%# string.Format("{0:c}", ((DataRowView)Container.DataItem)["字段名"])%>
      Container.DataItem相当于数据库中某个表或者视图中的一行记录,而一行可以有很多
列。  
      用String.Format方法设定字段的显示样式。例如c代表货币,p代表百分号,d代表短日期格
式显示,f代表浮点数现实,f3代表小数点后三为,一次类推。
       
       类型转换例子:<%# (int)((DataRowView)Container.DataItem)["字段名1"]*(int)
((DataRowView)Container.DataItem)["字段名2"]%>    意思是2个字段相乘。
    
上 面三种绑定方法的效率:Eval方法执行时候会调用DataBinder.Eval方法,DataBinder.Eval
方法在运行时使用反射执行后期绑 定计算,会导致性能明显下降。所以会导致性能明显下降。所以
三者中<%#((DataRowView)Container.DataItem)[" 字段名"] %>的性能最好。

今天就先写到这里,实在太晚了,抽时间继续写XPath()。

Feedback

#1楼 [楼主]   回复  引用  查看    

2008-03-28 09:14 by 落花人独立       
浅谈.NET中的数据绑定表达式(二)
这一节继续来谈.NET中的数据绑定表达式。

本节涉及的内容如下:
1,数据绑定方法的来源以及在低层上的实现。
2,数据绑定方法的执行效率排序。
<% #Container.DataItem %>
<% #GetDataItem() %>
<% # Eval ( " 字段名 " ) %>
<% #DataBinder.Eval(Container.DataItem, " 字段名 " ) %>
<% #((DataRowView)Container.DataItem)[ " 字段名 " %>
<% #((Type)Container.DataItem).成员  %>
<% #((Type)GetDataItem()).成员  %>
上面七种绑定形式以及它们的变幻形式都用过吗?性能怎么排序?

复习一下:
第一节 我们主要谈了数据绑定表达式的各种形式,在ASP.NET页面中出现的位置,以及我们常绑定到与数据库有关的 DataView,DataTable,DataSet 等数据源的数据绑定表达式的各种形式。

你有没有对Eval方法和DataBinder.Eval方法好奇过?
在.NET2.0中我们经常用Eval方法在Repeater,DataList,GridView等循环控件中绑定数据,Eval方法和DataBinder.Eval方法在低层是怎么实现的?它们到底有什么千丝万缕的关系?


一,来源、实现。
我 们常用的Eval方法其实是Page类的一个静态单向只读方法,而且它是一个受保护的方法。实际上Page类的Eval方法是继承自 TemplateControl类的。TemplateControl 类是一个抽象类,它为Page 类和 UserControl 类提供通用属性和方法。我们先来看一下继承家谱:

System.Object
   System.Web.UI.Control
    System.Web.UI.TemplateControl
       System.Web.UI.Page
       System.Web.UI.UserControl

Eval方法就是TemplateControl类的方法,它有两种形式:
名称 说明
TemplateControl.Eval (String) 计算数据绑定表达式。
TemplateControl.Eval (String, String) 使用用于显示结果的指定格式字符串计算数据绑定表达式。

事实上TemplateControl类还提供了XPath方法和XPathSelect方法供Page类和UserControl继承。这2个方法是和XML数据源有关的绑定方法。
如果细心的你查看TemplateControl类的基类Control类,你就会发现其实Control类并没有提供Eval,XPath,XPathSelect等方法。所以Eval,XPath等方法最终是在TemplateControl类中实现的。
现在,终于找到了Eval,XPath等数据绑定方法的来源了。
Eval,XPath等方法是.NET 2.0新增的方法。在.NET 1.1时代我们经常用的是DateBinder.Eval方法。形如:

<%#DataBind.Eval(Container.DataItem,"字段名"%>
<%#DataBind.Eval(Container.DataItem,"字段名","{0:c}"%>

Eval的出现其实就是为了简化DataBinder.Eval方法的写法从而代替它。
在ASP.NET 2.0中及以上,当我们调用Eval时,Eval 方法会使用GetDataItem方法调用DataBinder.Eval方法计算表达式的值
要想理解这句话,就算查边MSDN也一头雾水,除非我们知道Eval方法的源代码,否则根本找不到蛛丝马迹。这里就要用到反射了。我们通过反射获得了Eval方法的源代码:

protected   internal   object   Eval(string   expression)   
  {   
            
this
.CheckPageExists();   
            
return   DataBinder.Eval(this
.Page.GetDataItem(),   expression);   
  }   

终于见到GetDataItem()方法了,其实它就是Page类的 一个方法,也是.NET 2.0新增一个方法。GetDataItem()方法的作用是为了获得Container.DataItem,它是.NET 2.0中用来代替Container.DataItem的,如果你曾经用Repeater和DataList等绑定过数组或者ArrayList等,你就 会发现<%#GetDataItem()%>和<%#Container.DataItem%>等价。同时,可以肯定:Eval方法在低层上确实是调用DataBinder.Eval方法实现数据绑定的其中“this.CheckPageExists();” 是检查调用的时候有没有Page对象的,如果没有则会抛出一个异常

要弄清Eval是怎么工作的,GetDataItem()方法的低层实现我们也要用反射来获取:

public object GetDataItem()
    {
        
if ((this._dataBindingContext == null|| (this._dataBindingContext.Count == 0
))
        {
            
throw new InvalidOperationException(SR.GetString("Page_MissingDataBindingContext"
));
        }
        
return this
._dataBindingContext.Peek();
    }   

我们从GatDataItem()方法中看到“return   this._dataBindingContext.Peek();”很快就猜想_dataBindingContext是不是一个堆栈呢?事实它就是一个堆栈!通过反射查看源代码我们得出:_dataBindingContext是一个Stack类型对象。所以它有Peek方法。“return   this._dataBindingContext.Peek(); ”正是把堆栈顶部的元素返回。而if语句是用来判断这个堆栈是否已经存在或者是否已经有元素存在,如果if不成立,就会抛出一个异常。

从上面的分析我们知道:_dataBindingContext堆栈的作用是通过GetDataItem()方法这个桥梁向Eval方法提供Container.DateItem。用逆向思维来理解上面这句话:Eval方法可以自动计算出Container.DataItem,原因就是从
dataBindingContext 堆栈来获取Container.DataItem;这也就为什么Eval方法能够知道形如<%#Eval"字段名"%>中字段名隶属于哪个数 据项的属性的原因;同时我们也知道.NET 2.0中的Eval在本质上的实现并没有抛弃Container.DataItem,而Container.DataItem在2.0时代也没有消失。

那么_dataBindingContext这个保存Container.DataItem的堆栈是怎么建立的呢?
我 们很快就想到每次绑定控件时候最后那条语句是什么:this.控件ID.DataBind();对就是DataBind()方法,DataBind()方 法还有一个重载:DataBind(bool raiseOnDataBinding)。为_dataBindingContext这个堆栈压入元素和弹出元素的方法正是用DataBind(bool flag)这个重载方法实现的。
DataBind(bool raiseOnDataBinding)在低层的实现:

 protected virtual void DataBind(bool raiseOnDataBinding)
    {
        
bool flag1 = false;//这个标志的用处在上下文中很容易推出来,如果有DataItem压栈,则在后面出栈。   

        if (this.IsBindingContainer)//判断控件是不是数据绑定容器,实际上就是判断控件类是不是实现了INamingContainer   
        {
            
bool
 flag2;
            
object obj1 = DataBinder.GetDataItem(thisout   flag2);//这个方法是判断控件是不是有DataItem属性,并把它取出来。   

            if (flag2 && (this.Page != null))//如果控件有DataItem   
            {
                
this.Page.PushDataBindingContext(obj1);//把DataItem压栈,PushDataBindingContext就是调用_dataBindingContext的Push方法   

                flag1 = true;
            }
        }
        
try

        {
            
if (raiseOnDataBinding)//这里是判断是不是触发DataBinding事件的。   
            {
                
this
.OnDataBinding(EventArgs.Empty);
            }
            
this.DataBindChildren();//对子控件进行数据绑定,如果这个控件有DataItem,则上面会将DataItem压入栈顶,这样,在子控件里面调用Eval或者GetDataItem方法,就会把刚刚压进去的DataItem给取出来。   

        }
        
finally

        {
            
if (flag1)//如果刚才有压栈,则现在弹出来。   
            {
                
this.Page.PopDataBindingContext();//PopDataBindingContext就是调用_dataBindingContext的Pop方法   

            }
        }
    }   


当我们执行到this.控件ID.DataBind();时候。在低层上就会调用这个重载的方法来准备包含DataItem的_DatBindingContext堆栈。
上面的代码中提到了DataBinding事件,那么它一般什么时候被触发呢?
1,如果用编程方式,那么在我们调用DataBind()方法时候自动触发DataBinding事件。
2,如果我们用数据源控件(例如SqlDataSource等),当把控件绑定到数据源控件时候,这个事件就会自动触发。
一般数据绑定表达式常常放在模板中循环显示数据,例如Repeater和DataList等的模板。那么下面这个知识点应该知道:Repeater,DataList,FormView等控件必须使用模板,如果不使用模板,这些控件将无法显示数据。而GridView,DetailsView,Menu等控件也支持模板,但显示数据时不是必须的。而TreeView控件不支持模板。
注意:
一般情况下,数据绑定表达式不会自动计算它的值,除非它所在的页或者控件显示调用DataBind()方法。DataBind()方法能够将数据源绑定到被调用的服务器控件及其所有子控件,同时分析并计算数据绑定表达式的值。
终于写的有点眉目了,好累!我们该回头看看Eval方法调用的静态DataBinder.Eval方法在低层的实现了。我把DataBinder类的源代码贴出来:

namespace  System.Web.UI
{
    
using  System;
    
using  System.Collections;
    
using  System.ComponentModel;
    
using  System.Globalization;
    
using  System.Reflection;
    
using  System.Security.Permissions;
    
using  System.Web;

    [PermissionSet(SecurityAction.LinkDemand, XML
= " <PermissionSet class=" " System.Security.PermissionSet" " "r"n               version=" " 1 " " >"r"n   <IPermission class=" " System.Web.AspNetHostingPermission, System, Version = 1.0 . 5000.0 , Culture = neutral, PublicKeyToken = b77a5c561934e089" " "r"n                version=" " 1 " " "r"n                Level=" " Minimal" " />"r"n</PermissionSet>"r"n " )]
    
public  sealed  class  DataBinder
    {
        
private  static  readonly  char [] expressionPartSeparator  =  new  char [] {  ' . '  };
        
private  static  readonly  char [] indexExprEndChars  =  new  char [] {  ' ] ' ' ) '  };
        
private  static  readonly  char [] indexExprStartChars  =  new  char [] {  ' [ ' ' ( '  };

        
public  static  object  Eval( object  container,  string  expression)
        {
            
if  (expression  ==  null )
            {
                
throw  new  ArgumentNullException( " expression " );
            }
            
if  (container  ==  null )
            {
                
return  null ;
            }
            
string [] expressionParts  =  expression.Trim().Split(expressionPartSeparator);
            
return  Eval(container, expressionParts);
        }

        
private  static  object  Eval( object  container,  string [] expressionParts)
        {
            
object  propertyValue  =  container;
            
for  ( int  i  =  0 ; (i  <  expressionParts.Length)  &&  (propertyValue  !=  null ); i ++ )
            {
                
string  propName  =  expressionParts[i];
                
if  (propName.IndexOfAny(indexExprStartChars)  <  0 )
                {
                    propertyValue 
=  GetPropertyValue(propertyValue, propName);
                }
                
else
                {
                    propertyValue 
=  GetIndexedPropertyValue(propertyValue, propName);
                }
            }
            
return  propertyValue;
        }

        
public  static  string  Eval( object  container,  string  expression,  string  format)
        {
            
object  obj2  =  Eval(container, expression);
            
if  ((obj2  ==  null ||  (obj2  ==  DBNull.Value))
            {
                
return  string .Empty;
            }
            
if  ((format  !=  null &&  (format.Length  !=  0 ))
            {
                
return  string .Format(format, obj2);
            }
            
return  obj2.ToString();
        }

        
public  static  object  GetIndexedPropertyValue( object  container,  string  expr)
        {
            
if  (container  ==  null )
            {
                
throw  new  ArgumentNullException( " container " );
            }
            
if  ((expr  ==  null ||  (expr.Length  ==  0 ))
            {
                
throw  new  ArgumentNullException( " expr " );
            }
            
object  obj2  =  null ;
            
bool  flag  =  false ;
            
int  length  =  expr.IndexOfAny(indexExprStartChars);
            
int  num2  =  expr.IndexOfAny(indexExprEndChars, length  +  1 );
            
if  (((length  <  0 ||  (num2  <  0 ))  ||  (num2  ==  (length  +  1 )))
            {
                
throw  new  ArgumentException(HttpRuntime.FormatResourceString( " DataBinder_Invalid_Indexed_Expr " , expr));
            }
            
string  propName  =  null ;
            
object  obj3  =  null ;
            
string  s  =  expr.Substring(length  +  1 , (num2  -  length)  -  1 ).Trim();
            
if  (length  !=  0 )
            {
                propName 
=  expr.Substring( 0 , length);
            }
            
if  (s.Length  !=  0 )
            {
                
if  (((s[ 0 ==  ' " ' &&  (s[s.Length  -  1 ==  ' " ' ))  ||  ((s[ 0 ==  ' " '' ) && (s[s.Length - 1] ==  ' " '' )))
                {
                    obj3 
=  s.Substring( 1 , s.Length  -  2 );
                }
                
else  if  ( char .IsDigit(s[ 0 ]))
                {
                    
try
                    {
                        obj3 
=  int .Parse(s, CultureInfo.InvariantCulture);
                        flag 
=  true ;
                    }
                    
catch  (Exception)
                    {
                        obj3 
=  s;
                    }
                }
                
else
                {
                    obj3 
=  s;
                }
            }
            
if  (obj3  ==  null )
            {
                
throw  new  ArgumentException(HttpRuntime.FormatResourceString( " DataBinder_Invalid_Indexed_Expr " , expr));
            }
            
object  propertyValue  =  null ;
            
if  ((propName  !=  null &&  (propName.Length  !=  0 ))
            {
                propertyValue 
=  GetPropertyValue(container, propName);
            }
            
else
            {
                propertyValue 
=  container;
            }
            
if  (propertyValue  ==  null )
            {
                
return  obj2;
            }
            
if  ((propertyValue  is  Array)  &&  flag)
            {
                
return  (( object []) propertyValue)[( int ) obj3];
            }
            
if  ((propertyValue  is  IList)  &&  flag)
            {
                
return  ((IList) propertyValue)[( int ) obj3];
            }
            PropertyInfo info 
=  propertyValue.GetType().GetProperty( " Item " , BindingFlags.Public  |  BindingFlags.Instance,  null null new  Type[] { obj3.GetType() },  null );
            
if  (info  ==  null )
            {
                
throw  new  ArgumentException(HttpRuntime.FormatResourceString( " DataBinder_No_Indexed_Accessor " , propertyValue.GetType().FullName));
            }
            
return  info.GetValue(propertyValue,  new  object [] { obj3 });
        }

        
public  static  string  GetIndexedPropertyValue( object  container,  string  propName,  string  format)
        {
            
object  indexedPropertyValue  =  GetIndexedPropertyValue(container, propName);
            
if  ((indexedPropertyValue  ==  null ||  (indexedPropertyValue  ==  DBNull.Value))
            {
                
return  string .Empty;
            }
            
if  ((format  !=  null &&  (format.Length  !=  0 ))
            {
                
return  string .Format(format, indexedPropertyValue);
            }
            
return  indexedPropertyValue.ToString();
        }

        
public  static  object  GetPropertyValue( object  container,  string  propName)
        {
            
if  (container  ==  null )
            {
                
throw  new  ArgumentNullException( " container " );
            }
            
if  ((propName  ==  null ||  (propName.Length  ==  0 ))
            {
                
throw  new  ArgumentNullException( " propName " );
            }
            PropertyDescriptor descriptor 
=  TypeDescriptor.GetProperties(container).Find(propName,  true );
            
if  (descriptor  ==  null )
            {
                
throw  new  HttpException(HttpRuntime.FormatResourceString( " DataBinder_Prop_Not_Found " , container.GetType().FullName, propName));
            }
            
return  descriptor.GetValue(container);
        }

        
public  static  string  GetPropertyValue( object  container,  string  propName,  string  format)
        {
            
object  propertyValue  =  GetPropertyValue(container, propName);
            
if  ((propertyValue  ==  null ||  (propertyValue  ==  DBNull.Value))
            {
                
return  string .Empty;
            }
            
if  ((format  !=  null &&  (format.Length  !=  0 ))
            {
                
return  string .Format(format, propertyValue);
            }
            
return  propertyValue.ToString();
        }
    }
}

二,执行效率

从“一”讲述的低层实现。我们很容易来排序下面数据绑定表达式的执行效率
<% #Container.DataItem %>
<% #GetDataItem() %>
<% # Eval ( " 字段名 " ) %>
<% #DataBinder.Eval(Container.DataItem, " 字段名 " ) %>
<% #((DataRowView)Container.DataItem)[ " 字段名 " %>
<% #((Type)Container.DataItem).成员  %>
<% #((Type)GetDataItem()).成员  %>

1,效率最高应该是:

<%#((Type)Container.DataItem).成员 %>
<%#Container.DataItem%>
<%#((DataRowView)Container.DataItem)["字段名"%>

2,效率排第二的是:

<%#((Type)GetDataItem()).成员 %>
<%#GetDataItem()%>

3,效率最低的是:
<%#Eval("字段名")%>
<%#DataBinder.Eval(Container.DataItem,"字段名")%>

其实按上面的排序有失公允,原因是这七种数据表达绑定形式运用的场合不是完全相同的。

使用场合大概如下:
1,
<%#Eval("字段名")%>

<%#DataBinder.Eval(Container.DataItem,"字段名")%>
它 们的使用场合最广,数据源可以为与数据库有关的DataSet,DataTable,DataView。也可以为普通集合(例如:数组, ArrayList,HashTable等)和泛行集合(例如:List<T>,Dictionary<Tkey, Tvalue>等)。
注:它们2个永远可以相互替换,至少目前是这样,凡是可以用Eval方法的地方,就可以用 DataBinder.Eval方法替换。从低层实现上,Eval比DataBinder.Eval方法效率稍低,原因是Eval方法对了调用 GetDataItem()方法这一步。但最终都是通过DataBinder.Eval方法利用反射技术根据名称查找属性,从而计算出表达式的值,所以非 常影响性能。
2,
<%#((DataRowView)Container.DataItem)["字段名"
%>
它只能使用在数据源为与数据库有关的Dataset,DatTable,DataView。这些数据源都实现了IListSource接口。其实从低层实现本质上来看,它和<%#((Type)Container.DataItem).成员 %>类似。

3,
<%#Container.DataItem%>

<%#GetDataItem()%>
<%#((Type)Container.DataItem).成员 %>
<%#((Type)GetDataItem()).成员 %>
这 几种形式估计大家最不常用。它们一般只使用与普通集合(例如:数组,ArrayList,HashTable)和泛行集合(例如:List< T>,Dictionary<Tkey,Tvalue>)。其实本质上就是实现了IList,ICollection, IEnumerable,IDictionary等以及这些接口对应的泛行接口的集合。IList接口和IDictionary接口的区别是,一个只有 值,而另一个是键/值对,对应泛行形式也是这样。而Array就对用List<T>,而HashTable就对应 Dictionary<Tkey,Tvalue>。

先写到这里吧,实在太累了。
抽时间把不常用的数据绑定表达式运用一下,举点例子。同时把Bind和XPan绑定方法演示下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值