[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的屬性設置如下圖:

 運行結果圖:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM