[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的属性设置如下图:
运行结果图: