天天看点

一句代码实现批量数据绑定[下篇]一、通过DataPropertyAttribute特性过滤实体的数据属性二、Control/DataSource映射的表示:BindingMapping三、如何建立Control/DataSource映射集合四、通过映射集合实现数据绑定五、通过映射集合实现数据捕捉

Tree的方式进行属性操作(属性赋值和取值),添加了“数据捕捉”(Data

Capture)的功能,以实现将控件中的值赋给指定的实体。但是,这并不意味着这就是一个最终版本,这里面依然有一些问题,比如对空值的处理不不够全面,比如在进行数据绑定的时候,有的控件类型需要进行HTML

目录: 一、通过DataPropertyAttribute特性过滤实体的“数据属性” 二、Control/DataSource映射的表示:BindingMapping 三、如何建立Control/DataSource映射集合 四、通过映射集合实现数据绑定 五、通过映射集合实现数据捕捉

DataBinder在进行数据绑定的时候,并没有对作为数据源的对象作任何限制,也就是说任何类型的对象均可作为数据绑定的数据源。控件(这里指TextBox、Label等这样绑定标量数值的控件)绑定值来源于数据源实体的某个属性。但是一个类型的属性可能有很多,我们需要某种筛选机制将我们需要的“数据属性”提取出来。这里我们是通过在属性上应用DataPropertyAttribute一个特性来实现的。

简单起见,我不曾为DataPropertyAttribute定义任何属性成员。DataPropertyAttribute中定义了一个静态的GetDataProperties方法,得到给定实体类型的所有数据属性的名称。但是为了避免频繁地对相同实体类型进行反射,该方法对得到的属性名称数组进行了缓存。

不论是数据绑定(实体=〉控件),还是数据捕捉(控件=〉实体)的实现都建立在两种之间存在着某种约定的映射之上,这个映射是整个DataBinder的核心所在。在这里,我定义了如下一个BindingMapping类型表示这个映射关系。

这里我主要介绍一下各个属性的含义:

DataSourceType:作为数据源实体的类型;

Control:需要绑定的控件;

ControlValueProperty:数据需要绑定到控件属性的名称,比如TextBox是Text属性,而RadioButtonList则是SelectedValue属性;

DataSourceProperty:实体类型中的数据属性名称

AutomaticBind:是否需要进行自动绑定,通过它阻止不必要的自动数据绑定行为。默认值为True,如果改成False,基于该条映射的绑定将被忽略;

AutomaticUpdate:是否需要进行自动更新到数据实体中,通过它阻止不必要的自动数据捕捉行为。默认值为True,如果改成False,基于该条映射的数据捕捉定将被忽略;

FormatString:格式化字符串;

ControlValuePropertyType:控件绑定属性的类型,比如TextBox的绑定属性为Text,那么ControlValuePropertyType为System.String;

DataSourcePropertyType:实体属性类型。

需要补充一点的是:ControlValuePropertyType和DataSourcePropertyType使用到了之前定义的用于操作操作属性的组件ProcessAccessor。BindingMapping采用了克隆模式。

BindingMapping表示的一个实体类型的数据属性和具体控件之间的映射关系,而这种关系在使用过程中是以批量的方式进行创建的。具体来说,我们通过指定实体类型和一个作为容器的空间,如果容器中的存在满足映射规则的子控件,相应的映射会被创建。映射的批量创建是通过DataBinder的静态方法BuildBindingMappings来实现的。

在具体介绍BuildBindingMappings方法之前,我们需要先来讨论一个相关的话题:在进行数据绑定的时候,如何决定数据应该赋值给控件的那个属性。我们知道,不同的控件类型拥有不同的数据绑定属性,比如TextBox自然是Text属性,CheckBox则是Checked属性。ASP.NET在定义控件类型的时候,采用了一个特殊性的特性ControlValuePropertyAttribute来表示那个属性表示的是控件的“值”。比如TextBox和CheckBox分别是这样定义的。

在这里我们直接将ControlValuePropertyAttribute中指定的名称作为控件绑定的属性名,即BindingMapping的ControlValueProperty属性。该值得获取通过如下一个GetControlValuePropertyName私有方法完成。为了避免重复反射操作,这里采用了全局缓存。

最终的映射通过如下定义的BuildBindingMappings方法来建立,缺省参数suffix代表的是控件的后缀,其中已经在《上篇》介绍过了。

DataBinder设计的目标是让默认的绑定行为解决80%的问题,并且提供给相应的方式去解决余下的问题。为了让开发者能够有效解决余下的这20%的绑定问题,我们定义两个事件:DataItemBinding和DataBound,它们分别在进行绑定之前和之后被触发。关于事件的触发,已经体现在OnBindData方法的定义中了。

数据绑定使用到的实际上是Entity-〉Control映射,如果我们借助控件到Control-〉Entity,就能实现自动捕获控件的值然后将其保存到给定的实体对象上。我为此在DataBinder上定义了两个重载的UpdateData方法。

UpdateData方法的实现和BindData方法的逻辑基本一致,将Control和Entity呼唤一下而已,所以在这里我就不再赘言叙述了。

<a href="http://www.cnblogs.com/artech/archive/2011/03/23/databinding.html">一句代码实现批量数据绑定[上篇]</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/27/databinding2.html">一句代码实现批量数据绑定[下篇]</a>

作者:蒋金楠

微信公众账号:大内老A

如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

<a href="http://www.cnblogs.com/artech/archive/2011/03/27/databinding2.html" target="_blank">原文链接</a>

继续阅读