WPF中数据绑定的Validation应用分析

本来在写WPF Bug清单系列,但是写到第三篇(突然消失的ListViewItem)的时候发现重现BUG的逻辑很复杂。而且需要比较多的基础知识,如果不先解释清楚,实在是怕有人用“不用Valiation不就行了”等回复来砸场子。^_^

 

本文从设计和应用的角度对DataBindingValidation的不足进行了分析,假设读者使用过DataBinding中的Validation着重介绍WPFDataBindingValidation。有关数据绑定的基础知识请参考MSDN

 

有的人很不欢喜用Data Binding,无论是WPF还是WinForm的。认为自己控制数据同步更新不就好了?如果只是一个登录框或是写着玩的程序,也绝对没有什么问题。但是如果是在具有大量分层次的数据结构的企业级程序中,手动地进行UI与后台数据的更新,不仅工作量繁重,而且容易出错。(WPF固然有很多BUG,但是我们也不应该因此不用吧。)

 

多数情况下,由ValiationRule继承来的简单Rule可以完成多数数据绑定的验证。比如StringRequiredRuleLengthContraintRuleRegexValidationRule等等,在CodePlex上已经存在这样一个简单Rule库的项目。(让人诧异的是这个没几行代码的东西还在Beta

 

但是对于稍稍复杂一点的Validation,一般的ValidationRule就无能为力了。

 

比如下面的Person类。

 

    public class Person

    {

        public int MaxAge = 1000;

        public int MinAge = 0;

        public int Age { get; set; }

    }

 

这时,要验证Age,就要取到MaxAgeMinAge的值。但是这个值在.NET Framework 3.0ValidationRule里是取不到的(3.5 SP1中可在BindingGroupValidation中取到)。这还只是在兄弟属性里找,如果Person有个Parent属性,我们要验证Parent是否存在,就要获取到所有的Person

 

这时我们就要祭出.NET Framework 3.5引入的DataErrorValidationRule或是.NET Framework 3.5 SP1引入的BindingGroup。(未发布的.NET Framework 4.0其实才能算是WPF的完整版,其中加入了多个重要组件。)

 

PS:面对3.03.5的简陋,不想频繁跟进.NET的更新都不行。(或者说新版更诱人好听些)

 

简单起见,本篇将着重介绍DataErrorValidationRule ,毕竟其所依赖的IDataErrorInfo接口早在.NET Framework 1.0中就已经存在。如果遗留系统中的数据定义已经使用这个接口进行数据的验证,那么通过DataErrorValidationRule移植到WPF也是会带来一定方便的。(如果真要移的话。)

 

使用IDataErrorInfo接口,简单点,直接实现这个接口就可以了,但是会让这个类非常的臃肿;因为这样会把一堆数据验证逻辑写在数据类中。我们知道,类的功能应该单一,所以我们就需要建立一整套类来进行数据验证。把验证逻辑独立出来。这个是与主题无关的设计问题,就不在这里深入讨论了。在使用数据验证时,我们不得不面对如下几个事实。

1.       一些情况下,一个数据更改(比如删除一个数据项),可能会产生多个验证错误。所以就需要维护一个当前Errors列表。然后,一系列针对这个列表的CRUD操作随之而来。这个也还好。主要问题是下面的。

2.       数据验证的逻辑是针对数据类的,就是这个类的每个实例都应该有相同或类似的验证逻辑。但是,Data BindingValidation是针对数据实例的。针对数据实例没有什么问题。但是也许是为了节省内存,WPF的实现导致了Validation使用上的一个不便——UI上不可见的控件,是不会自动地做Validation的。

3.       因为事实2的存在,我们会手动的去对数据进行Validation。问题又来了,手动地ValidationUI层不知道啊。出了错,UI也不会根据ErrorTemplate自动更改UI(比如自动地显示红框出来)。如何让UI知道它出错了呢?一个方法是触发相应的PropertyChanged事件。

4.       一部分的BusinessObject具有IsDirty属性(参见CSLA.NET框架),用来标识这个对象有没有发生过变化。有时就会用PropertyChanged事件来对IsDirty属性进行操作。而这又与3中的解决方案冲突……一系列问题都出来了。

 

关于上面的问题本来想写一个带有示例的WPF Bug列表文章。但是其实这个不是WPFBug,只是使用上的不方便的地方(非常不便)。所以单独写了一篇解释一下。希望能给使用或将要使用WPFValidation的朋友们一些提示。

 

由于时间所限,很多内容没有展开,只是点到而已。如果有写得太不像话的地方——不要客气。

 

 

posted on 2008-12-16 21:59  南柯之石  阅读(2032)  评论(3编辑  收藏  举报

导航