原文:http://www.manuelabadia.com/blog/PermaLink,guid,678ed6d8-dce8-40d7-9117-0ffd016fe886.aspx
新的数据源控件和数据绑结构是很棒的特性,它可以简化程序的调试时间(尤其是对简单需求和没有太多framewark知识的人)。然而,对于一个核心开发者来说,因为封装而不是很正确完整的了解数据绑定的结构,是很是问题和不幸的,没有很完善的文档来说明它.... 我将解释一些不易理解的“magic”。
BaseDataBoundControl
被设计为使用 ASP.NET 数据源控件的数据绑定控件从 BaseDataBoundControl 控件类派生,该控件类定义基数据绑定控件的功能。这个类有下面的公共方法。
virtual object DataSource { get; set; }
virtual string DataSourceId { get; set; }
和下面的受保护的方法
protected abstract void PerformSelect();
protected abstract void ValidateDataSource(object dataSource);
第一个(DataSource)我们用来绑定数据在asp.net 1.x.第二个(DataSouceID)是使一个数据绑定控件“工作”在一个数据源控件上。当设置 DataSource 属性时,将调用 ValidateDataSource 方法,它验证数据绑定控件绑定到的对象是它可以使用的对象(通常是IListSource,IEnumerable或者IDataSouce).更多的受保护方法回来在再讲.
如果你更改DataSouceID在数据绑定控件初始化后,就会立刻显式调用DataBind方法。注意如果你在PreLoad之前设置DataSouceID,DataBind方式不会被调用。
这个类参与的页面生命周期:
*OnInit:如果视图状态(ViewState)是禁用的,控件每次PreRender将被绑定。
*OnPreLoad:设置一个内部标记表征在初始化(init)过程结束。
*OnPreRender:设置一个内部标记表征在开始PreRender过程,调用DataBind方法。
这个类有一个公共方法:
public override void DataBind();
这个方法调用受保护的方法PerformSelect,从关联数据源检索广告数据.
DataBoundControl
DataBoundControl继承自BaseDataBound,作为所有以列表或表格形式显示数据的数据绑定控件的基类使用。它添加了一个公共属性:
public virtual string DataMember { get; set; }
它是当数据源包含多个不同的数据项列表时,获取或设置数据绑定控件绑定到的数据列表的名称。
这个类完成的主要工作是隔离派生类获取来自数据源的数据(记住,控件可以使用DataSouce或者DataSouceID属性来绑定,它是支持这两种数据源的方式)。数据将出现在从IEnumerable派生来的类,重写下面的保护方法:
protected internal virtual void PerformDataBinding(IEnumerable data);
幸运的,很难的工作已经由ConnectToDataSourceView完成了,它得到一个数据源视图。最直接的方法是用DataSourceID绑定控件,但是作为数据源控件为了暴露数据源它必须对类封装(只读的数据源从IDataSouce实现,返回一个只支持select方法的视图(只读数据源视图))。
这个类参与的页面生命周期:
*OnPreLoad:调用基类OnPreLoad,若数据绑定控件还未绑定,如果是第一次页面请求且启动视图状态,去设置一个标识在OnPreRender过程试着去绑定数据。
*OnLoad:设法从数据源中得到视图(如果它还没有),如果某种原因在OnPreRender过程没有试着去绑定数据且数据没有被绑定,去设置一个标识在OnPreRender过程试着去绑定数据。
你看到了,当在PreLoad过程之前如果设置了DataSouceID,为了自动绑定数据,这个类补充了基类留下的未完成的。
如果数据绑定控件用DataSouceID去绑定,当数据源改变的时候,DataSourceView就会重新绑定,控件可以捕获到DataSouceViewChanged事件。
这个类实现的保护方法在BaseDataBoundControl属性中调用。ValidateDataSouce和PerformSelect已重写。第一个检查为 DataSource 属性设置的对象类型,确保其是 IDataSource、IListSource 或 IEnumerable 接口的实例,如果不是会触发一个异常。第二个(PerformSelect)在DatBind方法中被调用,做下面的事情:
*如果我们用DataSouce来绑定,触发DataBinding事件
*从数据源中得到数据源视图(DataSourceView)
*标记控件已经绑定
*建立select相关参数,调用DataSourceView的select方法,当Select方法完成后通过回调(提供一个执行任何自定义数据工作的 DataSourceViewSelectCallback 委托)来被调用。