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的屬性設置如下圖:
運行結果圖: