首页 > 代码库 > 使用ValidationRule类来检查用户输入的有效性

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

1 新建WPF应用程序ValidationRuleExp

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

 

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

 

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

 

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

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

详细代码如下所示。

<span style="font-family:SimSun;">//************************************************************
//
// 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));
            }
        } 
    }
}</span>
 

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类的完整代码。

<span style="font-family:SimSun;">//************************************************************
//
// 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 =http://www.mamicode.com/= null || string.IsNullOrEmpty(value.ToString().Trim()) || !IsTelePhone(value.ToString().Trim()))>

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

<span style="font-family:SimSun;"><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></span>

(2)MainWindow.xaml.cs

<span style="font-family:SimSun;">//************************************************************
//
// 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("大侠,我记住你了!");
            }
        }
    }
}</span>

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

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

1) 

<span style="font-family:SimSun;">Binding.Path="TelePhone"</span>

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

2)

<span style="font-family:SimSun;"><Binding.ValidationRules>
    <cr:ContactRule checkType="0"/>
</Binding.ValidationRules></span>

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

3)

<span style="font-family:SimSun;"><cr:ContactRule checkType="0"/></span>

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

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)验证未通过的条件为什么要这样写?

<span style="font-family:SimSun;">if (!CheckInput(this.TextBox_TelePhone) || !CheckInput(this.TextBox_MobilePhone) || !CheckInput(this.TextBox_Email) || !CheckInput(this.TextBox_HomePage)){
    return false;
}</span>
这样写可以确保就算有多个文本框存在验证错误时,也只会将第一个文本框的错误信息被弹出。

 

5 最后的总结

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

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