zoukankan      html  css  js  c++  java
  • [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的属性设置如下图:

     运行结果图:

  • 相关阅读:
    Flink实例(117):FLINK-SQL应用场景(16)以upsert的方式读写Kafka数据——以Flink1.12为例(二)
    Flink实例(116):FLINK-SQL应用场景(15)以upsert的方式读写Kafka数据——以Flink1.12为例(一)
    数据挖掘实践(17):基础理论(十七)数据挖掘基础(四)模型解释
    数据挖掘实践(16):基础理论(十六)数据挖掘基础(三)特征工程(二)性能度量与评估方法
    rust 可变变量
    Rust学习(32):智能指针-Rc<T>
    rust 高级编程
    rust 所有权
    rust智能指针
    Anbox:容器中的 Android,anboxandroid
  • 原文地址:https://www.cnblogs.com/shuiguang/p/2704985.html
Copyright © 2011-2022 走看看