自动绑定数据源
实现数据控件与原始数据的绑定是实现数据展示与编辑的基本前提。在常规的设计模式下实现数据绑定有两种方式:1)第一种方式:在窗体上引用数据对象→逐个拖放控件→分别设置控件与字段的绑定关系。这无疑是个不厌其烦的重复过程,是个没有任何创造性的过程,也是一个容易出现隐性bug的设计过程。
2)另一种方式:通过生成器指定物理表与控件的关系,由生成器完成控件与数据源的绑定。这里的变化不过是把事后定义改变成事前定义,虽然增加了自动化成分,但在数据源变化的时候这些结果也会同时付之东流。如果根据设计变化进行调整则会重复第一种方式的过程。
实现封装的目的就是要彻底摆脱这种低能、低效的重复工作。为此,我们给控件增加了“PI_绑定属性”,同时还要遵行命名规则的必要约束。
由于需要实现数据绑定的控件类不止这一个,所以实现绑定的方法并不是基于控件自身的封装,如果在窗体中封装了一个遍历的方法,就能通过一种简单的方式实现窗体内所有具备“PI_绑定属性”的数据源绑定问题。
“PI_绑定属性”具有双重作用:通知执行绑定的程序自身是否要参与绑定处理;如果非NULL则表示参与绑定。绑定程序会继续下面的动作:
1)得到“PI_绑定属性”的值;
2)从该值得到所规定的属性名(本例是控件原有的Text属性);
3)按规定的属性名(Text)取出属性中的值(本例是“TB_FR_名称”);
4)找到第一个下画线(与此前的字符个数无关),截取后面的部分作为字段名(本例应是:“FR_名称”);
5)按所得到的字段名(“FR_名称”)实现对数据集中对应字段的绑定。
初看来,这似乎是个“多此一举”的构思,其实不然,这里解决了两个非常重要的问题:
1)在窗体上布局数据控件并不需要配置数据源:“无错代码”是.NET所标榜的编程机制,这就会导致在设计状态下必须配置好数据源才能允许放置与数据绑定有关的控件。很多时候我们并不能在设计状态下确定数据源(只有在运行时才能给定),这就会给编程带来一系列麻烦的事。在代码中可以看到我们通过错误陷阱屏蔽了该环境下中的报错,所以就能在没有数据源的情况完成对“TB_”实例的引用。
2)可以在运行状态下配置数据源是提高编程效率的一个重要命题,这个设计为后续的自动化实现奠定了必要的基础,也为运行状态下的功能调整提供了可能性。
在这里还要说明以下几点:
1)也可以在“PI_绑定属性”中填写控件的“Name”属性,因为“Name =‘TB_FR_名称’”所以其效果相同。在一个系统中对“PI_绑定属性”的引用应当尽量保持一致,以便交流。
2)凡是继承了“ITF_绑定”接口的控件都有同样的功能。
3)按字段名称填写控件属性是个烦琐的工作,既然我们屏蔽了系统的自动化服务,势必就要建立自己的自动化机制,否则就不能达到提高效率的目的。这部分请参看第8.3节。
这种绑定经常与窗体上的Grid对象配合使用,承载控件的容器与Grid对象会通过更高层次的控件属性实现联动。在自定义Grid的过程中会进一步讨论这些问题。