[Winform控件编程系列之一]制作一个能验证错误的文本框和ErrorProvider的复合控件

    Winform控件编程 

     本人水平有限,写此博客的目的一是为了备忘,二是望高手指正,三是希望和大家交流,也许能给他人一些启示。

     也许你能在我的文章中找到许多似曾相识的代码和文字,没错,我确实是引用了许多网上的文章。但我敢保证的是,所有的代码我都调试过,且被我修改成我认为合适的代码。

     WinForm控件通常有三种类型:复合控件(Composite Controls),扩展控件(Extended Controls),自定义控件(Custom Controls)。  
      复合控件:将现有的各种控件组合起来,形成一个新的控件,将控件的功能集中起来。
      扩展控件:在现有控件的控件的基础上派生出一个新的控件,为原有控件增加新的功能或者修改原有控件的功能。
      自定义控件:直接从System.Windows.Forms.Control类派生出来。Control类提供控件所需要的所有基本功能,包括键盘和鼠标的事件处理。自定义控件是最灵活最强大的方法,但是对开发者的要求也比较高,你必须为Control类的OnPaint事件写代码。

     制作一个能验证错误的文本框和ErrorProvider的复合控件

      对于文本框的验证是一个经常需要用到的功能。你是如何验证用户输入的呢?是在文本框的KeyDown事件中添加代码扑捉按键,防止键入非法字符(比如只能输入数字的文本框);还是在文本框失去焦点时,使用代码验证错误,然后弹出一个错误消息框;或者你使用正则表达式对文本框实施验证。我在使用VB.NET时,如果我想使用户只能录入数字,喜欢用KeyDown事件处理用户按键来防止键入非数字。但我发现此方法有一定的缺陷,它不能防止你复制、粘贴或者使用代码改变文本框值的情形。

      正则表达式是许多人的选择,因为它不打扰用户输入,提高用户体验。但是如果在项目中的每个需验证的地方你都要添加文本框和ErrorProvider组件,是否太麻烦了。我们完全可以制作一个能验证错误的文本框和ErrorProvider组件的复合控件。

      第一步:新建一个.net 2.0 的Windows窗体控件库项目,修改UserControl1.cs的代码,将类继承的UserControl改为TextBox,修改类名为TextBoxValidation。返回设计视图,从工具箱中拖拽一个ErrorProvider组件到设计器中。并修改名称为txtErrorProvider。

     第二步:编码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace TextBoxErrorProvider
{

        /// <summary>
        /// 对文本框内容进行验证
        /// 有四个属性需要设置:errorMessage            错误的文本
        ///                     regexString             验证用的正则表达式
        ///                     validationIsEmpty       是否验证是空值
        ///                     validationIsEmptyString 验证为空的文本框显示的错误消息
        /// 一个方法:GetErrorMessage                   返回当前文本框控件的当前错误描述字符串。
        /// </summary>
        public partial class TextBoxValidation : TextBox
        {
            public TextBoxValidation()
            {
                InitializeComponent();
                //验证处理事件
                this.Validating += new CancelEventHandler(txtValidation_Validating);
            }

            private string m_errorMessage = "文本框输入错误";
            private bool m_validationIsEmpty = false;
            private string m_validationIsEmptyString = "文本框不能是空的";
            private string m_regexString = "";

            /// <summary>
            /// 验证用的表达式,默认是空的,即不验证。
            /// </summary>
            [Category("自定义属性"), Description("验证用的字符串表达式,默认是空的,即不验证。")]
            public string regexString
            {
                get { return m_regexString; }
                set { m_regexString = value; }
            }
            /// <summary>
            /// 错误消息
            /// </summary>
            [Category("自定义属性"), Description("用于设置使用正则表达式验证发生错误时显示的消息")]
            public string errorMessage
            {
                get { return m_errorMessage; }
                set { m_errorMessage = value; }
            }


            /// <summary>
            /// 是否验证文本框是空值,默认是不验证。
            /// </summary>
            [Category("自定义属性"), Description("是否验证文本框是空值,默认是不验证。")]
            public bool validationIsEmpty
            {
                get { return m_validationIsEmpty; }
                set { m_validationIsEmpty = value; }
            }
            /// <summary>
            /// 当验证文本框是空值时,显示的错误信息
            /// </summary>
            [Category("自定义属性"), Description("验证为空的文本框显示的错误消息")]
            public string validationIsEmptyString
            {
                get { return m_validationIsEmptyString; }
                set { m_validationIsEmptyString = value; }
            }


            /// <summary>
            /// 验证文本
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public virtual void txtValidation_Validating(object sender, CancelEventArgs e)
            {
                 if (string.IsNullOrEmpty(this.Text))
             {
                 if (m_validationIsEmpty)  //要求非空验证
                 {
                     txtErrorProvider.SetError(this, m_validationIsEmptyString);
                     return;
                 }
                 else
                 {
                     txtErrorProvider.SetError(this, "");
               }
            }
             else
            {
                if (m_regexString != null)
                {
                    if (!Regex.IsMatch(this.Text, m_regexString))
                    {
                        txtErrorProvider.SetError(this, m_errorMessage);
                    }
                    else
                    { txtErrorProvider.SetError(this, ""); }
                }
                else
                {
                    txtErrorProvider.SetError(this, "");
                }
            }
} /// <summary> /// 返回当前文本框控件的当前错误描述字符串。 /// </summary> /// <returns></returns> public string GetErrorMessage() { return this.txtErrorProvider.GetError(this); }       
//2012年9月27日21:47修改:为方便用户使用键盘输入,增加以下代码。
/// <summary>
        /// 当用户按下Enter键或者是向下的方向键时,将控件的焦点移走。
        /// 用户按下向上方向键时,将控件的焦点移到上一个控件。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
         private void TextBoxValidation_KeyDown(object sender, KeyEventArgs e)
        {
           Form controlForm = null;
            //当用户按下Enter键或者是向下的方向键时,将控件的焦点移走
           switch (e.KeyCode)
           {
               case Keys.Enter:case Keys.Down:
                   {
                       controlForm = this.FindForm();
                       if (controlForm != null)
                       {
                           controlForm.SelectNextControl(this, true, false, true, true);
                       }
                       break;
                   }
                case Keys.Up: // 用户按下向上方向键时,将控件的焦点移到上一个控件。
                   {
                       controlForm = this.FindForm();
                       if (controlForm != null)
                       {
                           controlForm.SelectNextControl(this, false, false, true, true);
                       }
                       break;
                   }
            }
        }

} }

 


     第三步:编译

     第四步:测试

     向解决方案中添加 windows窗体程序项目,在form1上拖拽四个textBoxValidation控件,四个label控件,形成如下图所示:

   为textBoxValidation1、textBoxValidation2添加TextChanged事件处理程序:

        //密码
        private void textBoxValidation1_TextChanged(object sender, EventArgs e)
        {
            this.textBoxValidation1.regexString = this.textBoxValidation2.Text;
        }
        //确认密码
        private void textBoxValidation2_TextChanged(object sender, EventArgs e)
        {
            this.textBoxValidation2.regexString = this.textBoxValidation1.Text;
        }

设置textBoxValidation1、textBoxValidation2的validationIsEmpty属性为true。


textBoxValidation3的属性设置如下图:

 

textBoxValidation4的属性设置如下图:

 运行结果图:

 

 

posted on 2012-09-27 11:13  水光  阅读(3952)  评论(8编辑  收藏  举报

导航