WPF的验证方案
来源:互联网 发布:linux rpm 卸载 编辑:程序博客网 时间:2024/06/05 04:43
今天在别人的博客上看到这个,转过来一下
想想以后会用得着。。。
1.通过继承ValidationRule抽象类,定义验证规则重写Validate方法
这里是sdk的示例代码
- public class AgeRangeRule : ValidationRule
- {
- private int _min;
- private int _max;
- public AgeRangeRule()
- {
- }
- public int Min
- {
- get { return _min; }
- set { _min = value; }
- }
- public int Max
- {
- get { return _max; }
- set { _max = value; }
- }
- public override ValidationResult Validate(object value, CultureInfo cultureInfo)
- {
- int age = 0;
- try
- {
- if (((string)value).Length > 0)
- age = Int32.Parse((String)value);
- }
- catch (Exception e)
- {
- return new ValidationResult(false, "Illegal characters or " + e.Message);
- }
- if ((age < Min) || (age > Max))
- {
- return new ValidationResult(false,
- "Please enter an age in the range: " + Min + " - " + Max + ".");
- }
- else
- {
- return new ValidationResult(true, null);
- }
- }
- }
然后是xaml的使用代码
- <TextBox Name="textBox1" Width="50" FontSize="15"
- Validation.ErrorTemplate="{StaticResource validationTemplate}"
- Style="{StaticResource textBoxInError}"
- Grid.Row="1" Grid.Column="1" Margin="2">
- <TextBox.Text>
- <Binding Path="Age" Source="{StaticResource ods}"
- UpdateSourceTrigger="PropertyChanged" >
- <Binding.ValidationRules>
- <c:AgeRangeRule Min="21" Max="130"/>
- </Binding.ValidationRules>
- </Binding>
- </TextBox.Text>
- </TextBox>
就是通过ValidationRules集合挂验证规则.如果逻辑不复杂的话,勉强可以接受,这里我个人认为可以作为界面的验证.但如果业务逻辑一旦发生变化,则意味着xaml文件一直需要修改,这并不是一种好的做法,并不推荐.(而且内置的验证规则太少了,有的话还勉强用用,都需要自己重写)
2.通过正则表达式附加属性简化写法,大家应该知道,验证部分,正则表达式占了很大部分.
定义一个正则表达式类,然后通过附加属性进行验证.具体的方案,请参考这里
http://www.codeproject.com/WPF/RegexValidationInWPF.asp
然后前端xaml的使用方法
- <TextBox
- Text="{Binding Path=EmailAddress, UpdateSourceTrigger=PropertyChanged}"
- jas:RegexValidator.RegexText="^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+/.[a-zA-Z]{2,4}$"
- jas:RegexValidator.ErrorMessage="Invalid e-mail address."
- />
代码是简化了,但有个缺点,只能定义一个验证规则,也存在着我上面提到的问题,把正则写在ui上面,并不是一个好的做法,应该对其进行封装(看着这么多符号就心慌,高手可以这么做),也并不推荐的做法.
3.与业务逻辑验证绑定在一起
这种做法与上面的都不同,因为业务逻辑的判断与常规的判断比如(比如是否必填,字符匹配等),而且前端只需要绑定字段就可以了,先看前端的做法
- <TextBox Width="100" Grid.Column="1" HorizontalAlignment="Left" Margin="5,5,0,5" x:Name="txtFirstName" Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" ToolTip="Enter customers first name." />
请注意,这里并没有写什么验证规则或正则表达式哦,真正的验证在这里,验证的对象必须实现IDataErrorInfo接口,通过索引器,可以判断对象的每个字段.
上面紧紧是FirstName,这里是通过整个对象的业务逻辑判断的,否则你需要在ui上面都定义一个验证规则,非常麻烦(比如有2个字段,你必须对两个字段都定义验证规则(即第一种方法)).这种做法是比较好的,把逻辑与ui分开了,值得推荐.sdk示例代码
- public class Person : IDataErrorInfo
- {
- private int age;
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
- public string Error
- {
- get
- {
- return null;
- }
- }
- public string this[string name]
- {
- get
- {
- string result = null;
- if (name == "Age")
- {
- if (this.age < 0 || this.age > 150)
- {
- result = "Age must not be less than 0 or greater than 150.";
- }
- }
- return result;
- }
- }
- }
但还有些问题,如果我在第3点的基础上,我还要加一个普通的判断,比如必填验证,长度验证,还是逃不了验证规则这一步.
这里我们要做出选择
把规则定义在ui上(变动太大,不适合,无奈之举)
写在业务逻辑里面(这样下来,逻辑未免太复杂)
4.以元数据的形式(在属性上挂标签)
在codeproject上,我找到一个比较完美的解决方案,作者自己重新定义了一套标签,使用也比较简单(代码是vb的,编译后再反编译用c#看:)),这种做法已经接近了要求.大家去看看这篇文章,非常的不错.其在还为前端提供了一个ui显示错误的一个下拉列表.不过通过这个例子,我又想到一个更好的东西.
5.使用EnterPrise Library Validation Application Block(再好不过)
由于wpf的属性使用了大量的依赖属性,我原以为这个好东西在wpf算是废了,通过第3点和第4点,我们终于可以引进这个企业级模块了。如下做法
- public abstract class BaseValidationEntity<T> : IDataErrorInfo, INotifyPropertyChanged
- {
- IDataErrorInfo Members#region IDataErrorInfo Members
- public string Error
- {
- get { return null; }
- }
- private T _entity;
- public bool Valid()
- {
- Validator<T> validator = ValidationFactory.CreateValidator<T>();
- ValidationResults results = validator.Validate(this);
- return results.Count == 0;
- }
- public string this[string name]
- {
- get
- {
- string result = null;
- Validator<T> validator = ValidationFactory.CreateValidator<T>();
- ValidationResults results = validator.Validate(this);
- if (results.Count > 0)
- {
- return results.First().Message;
- //foreach (var item in results)
- //{
- // result += item.Message;
- //}
- }
- return result;
- }
- }
- #endregion
- protected void OnPropertyChanged(string name)
- {
- PropertyChangedEventHandler handler = PropertyChanged;
- if (handler != null)
- {
- handler(this, new PropertyChangedEventArgs(name));
- }
- }
- INotifyPropertyChanged Members#region INotifyPropertyChanged Members
- public event PropertyChangedEventHandler PropertyChanged;
- #endregion
- }
- public class aa:BaseValidationEntity<aa>
- {
- private string firstName;
- [StringLengthValidator(4, 10,MessageTemplate="aaa")]
- [RegexValidator(@"/w+([-+.']/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*", MessageTemplate = "Invalid e-mail address")]
- public string FirstName
- {
- get { return firstName; }
- set { firstName = value;
- OnPropertyChanged("FirstName");
- }
- }
- }
我们看到熟悉的标签了,目前我认为这种方案最好,当然我们也可以通过配置xml来实现,这样真正做到了界面与逻辑分离。
上面一层的做到了逻辑上的验证,至于界面如何显示错误,我们可以通过Error属性来定制一个控件,这个暂不讨论了
在学习wpf的朋友,欢迎一起讨论。
- WPF的验证方案
- wpf验证方案讨论
- 关于WPF的验证
- 【wpf】wpf对数据的绑定验证
- WPF 验证不起作用的原因
- WPF中GIF不动的问题解决方案。
- WPF 验证
- 一个Form验证的方案
- 适合配置的验证方案
- WPF-18:输入验证的详细用法
- WPF中TreeView.BringIntoView方法的替代方案
- WPF实现录音和语音识别的两种方案
- WPF下ListView 绑定xml数据源的方案
- 一种简单的密码验证方案
- jenkins 集成 redmine 账户验证的方案
- 一种简单的密码验证方案2
- .NET 控件的许可验证方案
- wpf验证方法总结
- 个人使用的SourceInsight配置文件
- 如何为个人网站添加谷歌地图服务
- Grid Computing: Making The Global Infrastructure a Reality
- 通过注册表添加受信任站点
- Software Engineering: Evolution and Emerging Technologies
- WPF的验证方案
- Practical Packet Analysis: Using Wireshark to Solve Real-World Network Problems
- 提供一个免费的CSDN下载账号
- 信息文档安全管理方案
- C#页面遍历控件
- Dreamweaver CS3: The Missing Manual [ILLUSTRATED]
- Ruby by Example: Concepts and Code
- MySql承受数据量问题
- 统计应用中的失败案例