使用ValidationRule类来检查用户输入的有效性

Posted 三五月儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ValidationRule类来检查用户输入的有效性相关的知识,希望对你有一定的参考价值。

1 新建WPF应用程序ValidationRuleExp

整个程序的结构如下图所示。

 

程序运行起来后的效果如下图所示。

 

用户操作程序时,先输入固话、手机、Email、个人网站等信息,再点击右侧的“点我记住你”按钮,便可以保存用户输入的信息。

 

2 新建业务实体类ContactModel(类文件为ContactModel.cs)

ContactModel类包含固话、手机、Email、个人网站等属性,分别与界面的固话文本框、手机文本框、Email文本框、个人网站文本框绑定。ContactModel类实现INotifyPropertyChanged接口,这样一来,当ContactModel类的某一属性发生改变时,便可以向执行绑定的客户端发出某一属性值已更改的通知。例如:将ContactModel类的TelePhone属性与客户端的“固话”文本框进行绑定,一旦TelePhone属性的值发生改变,将会通知“固话”文本框更新自己的值。

详细代码如下所示。

//************************************************************
//
// ValidationRule类示例代码
//
// Author:三五月儿
// 
// Date:2014/07/11
//
// http://blog.csdn.net/yl2isoft
//
//************************************************************
using System.ComponentModel;
namespace ValidationRuleExp

    public class ContactModel : INotifyPropertyChanged
    
        /// <summary>
        /// 固话号码
        /// </summary>
        private string telePhone;
        public string TelePhone
        
            get
            
                return telePhone;
            
            set
            
                telePhone = value;
                NotifyPropertyChanged("TelePhone");
            
        
 
        
        /// <summary>
        /// 手机号码
        /// </summary>
        private string mobilePhone;
        public string MobilePhone
        
            get
            
                return mobilePhone;
            
            set
            
                mobilePhone = value;
                NotifyPropertyChanged("MobilePhone");
            
        
 
        /// <summary>
        /// 电子邮件地址
        /// </summary>
        private string email;
        public string Email
        
            get
            
                return email;
            
            set
            
                email = value;
                NotifyPropertyChanged("Email");
            
        
 
        /// <summary>
        /// 个人网站地址
        /// </summary>
        private string homePage;
        public string HomePage
        
            get
            
                return homePage;
            
            set
            
                homePage = value;
                NotifyPropertyChanged("HomePage");
            
        
 
        /// <summary>
        /// NotifyPropertyChanged事件
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        
            if (PropertyChanged != null)
            
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            
         
    
 

3 新建自定义的规则类ContactRule,该类继承自ValidationRule类

当应用使用WPF数据绑定模型时,可以将规则集合ValidationRules与绑定关联。这样一来,当绑定对象的绑定值发生改变时,则绑定引擎就会检查ValidationRule,确认绑定对象的值是否通过了ValidationRule类指定的验证规则。若成功通过验证,则调用属性的set方法为属性赋值;若未通过验证,则会给出提示,同时中止属性赋值操作。

这里的规则集合ValidationRules可以包含一个或多个ValidationRule对象。ValidationRule对象的类型可以是派生ValidationRule的自定义类,也可以内置的ExceptionValidationRule类。本例中使用自定义的规则类ContactRule,该类派生自ValidationRule并实现Validate方法Validate方法中对用户的输入进行验证,这里的数据验证主要是借助于正则表达式来完成的

另外,我们自定义的ContactRule类,还接受一个输入参数checkType,该参数可以告知ContactRule类需要验证的对象的类型,0代表固话,1代表手机,2代表Email,3代表个人网站。

下面给出ContactRule类的完整代码。

//************************************************************
//
// ValidationRule类示例代码
//
// Author:三五月儿
// 
// Date:2014/07/11
//
// http://blog.csdn.net/yl2isoft
//
//************************************************************
 
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Controls;
 
namespace ValidationRuleExp

    public class ContactRule :ValidationRule
    
        public int checkType  get; set; 
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        
            try
            
                if (checkType == 0)
                //固话
                    if (value == null || string.IsNullOrEmpty(value.ToString().Trim()) || !IsTelePhone(value.ToString().Trim()))
                    
                        return new ValidationResult(false, "大侠,你输入的固话号码有误!");
                    
                
                else if (checkType == 1)
                //手机
                    if (value == null || string.IsNullOrEmpty(value.ToString().Trim()) || !IsMobilePhone(value.ToString().Trim()))
                    
                        return new ValidationResult(false, "大侠,你输入的手机号码有误!");
                    
                
                else if (checkType == 2)
                //Email
                    if (value == null || string.IsNullOrEmpty(value.ToString().Trim()) || !IsEmail(value.ToString().Trim()))
                    
                        return new ValidationResult(false, "大侠,你输入的Email有误!");
                    
                
                else
                //HomePage
                    if (value == null || string.IsNullOrEmpty(value.ToString().Trim()) || !IsHomePage(value.ToString().Trim()))
                    
                        return new ValidationResult(false, "大侠,你输入的个人网址有误!");
                    
                
                return new ValidationResult(true, null);
            
            catch (Exception e)
            
                return new ValidationResult(false, e.Message);
            
        
 
        private bool IsTelePhone(string telePhone)
        
            return Regex.IsMatch(telePhone, @"^(\\d3,4-)?\\d6,8$");
        
 
        private bool IsMobilePhone(string mobilePhone)
        
            return Regex.IsMatch(mobilePhone, @"^[1]([3][0-9]1|59|58|88|89)[0-9]8$");  
        
 
        private bool IsEmail(string email)
        
            return Regex.IsMatch(email, @"\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
        
 
        private bool IsHomePage(string email)
        
            return Regex.IsMatch(email, @"http://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?");
        
    

4 编写程序画面代码

程序的主画面如下图所示。

 

画面中用到的主要控件如下表所示。

项号

控件类型

控件名称

绑定属性

说明

1

TextBox

TextBox_TelePhone

TelePhone

固话号码

2

TextBox

TextBox_MobilePhone

MobilePhone

手机号码

3

TextBox

TextBox_Email

Email

邮箱地址

4

TextBox

TextBox_HomePage

HomePage

个人网站地址

5

Button

Button_ClickMe

-

保存用户输入信息

下面是程序主画面的完整代码。

(1)MainWindow.xaml

<Window x:Class="ValidationRuleExp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cr="clr-namespace:ValidationRuleExp"
        Title="MainWindow" Height="300" Width="500" ResizeMode="NoResize">
    <Grid>
        <Label Content="固话:" Height="28" HorizontalAlignment="Left" Margin="32,69,0,0" Name="Label_TelePhone" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Right" Margin="0,71,228,0" Name="TextBox_TelePhone" VerticalAlignment="Top" Width="168" >
            <TextBox.Text>
                <Binding Path="TelePhone">
                    <Binding.ValidationRules>
                        <cr:ContactRule checkType="0"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Label Content="手机:" Height="28" HorizontalAlignment="Left" Margin="32,109,0,0" Name="Label_MobilePhone" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Right" Margin="0,109,228,0" Name="TextBox_MobilePhone" VerticalAlignment="Top" Width="168" >
            <TextBox.Text>
                <Binding Path="MobilePhone">
                    <Binding.ValidationRules>
                        <cr:ContactRule checkType="1"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Button Content="点我记住你!!!" Height="69" HorizontalAlignment="Left" Margin="295,81,0,0" Name="Button_ClickMe" VerticalAlignment="Top" Width="151" Click="ClickMe_Click" />
        <Label Content="大侠,请留下你的联系方式,以备我能随时骚扰你!" Height="28" HorizontalAlignment="Left" Margin="32,19,0,0" Name="Label_Notice" VerticalAlignment="Top" Foreground="Red" />
        <Label Content="Email:" Height="28" HorizontalAlignment="Left" Margin="32,156,0,0" Name="Label_Email" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="100,159,0,0" Name="TextBox_Email" VerticalAlignment="Top" Width="166" >
            <TextBox.Text>
                <Binding Path="Email">
                    <Binding.ValidationRules>
                        <cr:ContactRule checkType="2"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Label Content="个人网站:" Height="28" HorizontalAlignment="Left" Margin="32,206,0,0" Name="Label_HomePage" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="100,209,0,0" Name="TextBox_HomePage" VerticalAlignment="Top" Width="342" >
            <TextBox.Text>
                <Binding Path="HomePage">
                    <Binding.ValidationRules>
                        <cr:ContactRule checkType="3"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </Grid>
</Window>

(2)MainWindow.xaml.cs

//************************************************************
//
// ValidationRule类示例代码
//
// Author:三五月儿
// 
// Date:2014/07/11
//
// http://blog.csdn.net/yl2isoft
//
//************************************************************
 
using System.Windows;
using System.Windows.Controls;
 
namespace ValidationRuleExp

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    
        public MainWindow()
                    
            InitializeComponent();
            this.DataContext = new ContactModel();
            Contact.TelePhone = "010-22222222";
            Contact.MobilePhone = "15888888888";
            Contact.Email = "864003248@qq.com";
            Contact.HomePage = "http://blog.csdn.net/yl2isoft";
        
 
        //注意:此处省去了输入文本为空的校验
        public bool IsValidInput()
        
            if (!CheckInput(this.TextBox_TelePhone)
                || !CheckInput(this.TextBox_MobilePhone)
                || !CheckInput(this.TextBox_Email)
                || !CheckInput(this.TextBox_HomePage))
            
                return false;
            
            return true;
        
 
        private bool CheckInput(TextBox input)
        
            if (System.Windows.Controls.Validation.GetHasError(input))
            
                MessageBox.Show(System.Windows.Controls.Validation.GetErrors(input)[0].ErrorContent.ToString());
                return false;
            
            return true;
        
 
        private void ClickMe_Click(object sender, RoutedEventArgs e)
        
            if (IsValidInput())
            
                MessageBox.Show("大侠,我记住你了!");
            
        
    

MainWindow.xaml文件中的以下代码与数据验证有关(此处以TextBox_TelePhone文本框为例),所以下面将此部分代码特别提取出来进行重点说明。

<TextBox.Text>
    <Binding Path="TelePhone">
        <Binding.ValidationRules>
            <cr:ContactRule checkType="0"/>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>
针对这段代码,做以下几点说明:

1) 

Binding.Path="TelePhone"

通过此句代码可以设置绑定的源属性,将源对象的TelePhone属性绑定给目标对象的Text属性。本例中的源对象为ContactModel实例,目标对象为文本框TextBox_TelePhone。源对象是通过MainWindow.xaml.cs文件中的代码“this.DataContext = new ContactModel();”来设置的。

2)

<Binding.ValidationRules>
    <cr:ContactRule checkType="0"/>
</Binding.ValidationRules>

代码中,使用Binding.ValidationRules将用来检查用户输入的规则集合ValidationRules与Binding对象相关联,规则集合ValidationRules与Binding对象关联后,当用户的输入没有通过验证时,会在文本框的周围生成红色轮廓,以此来告知用户,该输入是不合法的。

3)

<cr:ContactRule checkType="0"/>

针对这句代码,再来啰嗦几句。

MainWindow.xaml文件一开始,使用代码xmlns:cr="clr-namespace:ValidationRuleExp"导入命名空间ValidationRuleExp,进而可以使用cr:ContactRule的方式来访问命名空间ValidationRuleExp中的ContactRule类了。


下面再来对MainWindow.xaml.cs文件中的代码进行说明。

点击画面按钮,执行ClickMe_Click()方法,方法中会调用IsValidInput()方法对用户输入进行验证,当用户输入的信息中存在错误时,会弹出错误信息提示框,否则,弹出“大侠,我记住你了!”的提示框(以此来模拟保存用户信息的操作)。

针对MainWindow.xaml.cs文件中的代码,重点说明以下几点:

1)使用System.Windows.Controls.Validation.GetHasError(input)来检查控件内容是否有误?

System.Windows.Controls.Validation.GetHasError()方法可以用来获取指定元素的附加属性HasError的值,HasError属性保存bool类型的值,当HasError的值为true时,说明指定元素的绑定存在验证错误,否则为 false。本例中使用该方法来检查文本框是否存在验证错误,若有误,则使用MessageBox.Show()方法输出错误信息。  

2)使用System.Windows.Controls.Validation.GetErrors(input)[0].ErrorContent.ToString()来获取验证错误信息。

System.Windows.Controls.Validation.GetErrors()方法可以获取指定元素的附加属性Errors的值。 通过访问附加属性Errors,可以获取与绑定相关联的 ValidationError对象的集合。ValidationError 则保存由绑定引擎产生的验证错误。 

3)验证未通过的条件为什么要这样写?

if (!CheckInput(this.TextBox_TelePhone) || !CheckInput(this.TextBox_MobilePhone) || !CheckInput(this.TextBox_Email) || !CheckInput(this.TextBox_HomePage))
    return false;
这样写可以确保就算有多个文本框存在验证错误时,也只会将第一个文本框的错误信息被弹出。

 

5 最后的总结

1)对用户输入的验证是在属性的set方法被执行前进行的,所以当用户的输入没有通过验证时,是不会触发属性的set方法的。

2)验证未通过时,给用户的唯一提示就是产生红框,要想弹出错误消息,需要借助System.Windows.Controls.Validation.GetErrors(input)[0].ErrorContent.ToString()来获取错误信息并使用MessageBox.Show()输出给用户。

 

源码下载地址

 

 

 

 

以上是关于使用ValidationRule类来检查用户输入的有效性的主要内容,如果未能解决你的问题,请参考以下文章

将 WPF ValidationRule 的状态传递给 MVVM 中的视图模型

验证规则 - 用户输入不能留空 - Python [重复]

具有依赖属性的 WPF ValidationRule

关于WPF的验证

WPF---数据绑定之ValidationRule数据校验

将 ComboBox 文本绑定到另一个 ComboBox 内的 ValidationRule?