使用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, @"^(\d{3,4}-)?\d{6,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()输出给用户。

 

源码下载地址

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值