winform,自定义文本框控件 实现文本框验证加水印功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winform,自定义文本框控件 实现文本框验证加水印功能相关的知识,希望对你有一定的参考价值。

需求:1、当文本框无值时出现灰色字体提示用户输入信息;

   2、当文本框有值时出现用户输入的值并且字体恢复黑色;

     3、当该文本框失去焦点时验证用户输入的值是否正确(正则表达式验证),如果错误,弹出“输入有误”消息框,并且使该文本框重新获取焦点;

用途:1、扩展控件避免了重复每个文本框控件都要写文本框内容发生改变时等事件;

          2、扩展性、复用性较强;

效果图如下:

文本框值为空时出现用户提示信息(自定义提示信息)

技术分享

当输入的值验证不通过时弹出消息框提示,并且该输入错误的文本框获取焦点

技术分享

 

代码

技术分享
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Windows.Forms;
  6 using System.ComponentModel;
  7 using System.Text.RegularExpressions;
  8 using System.Drawing;
  9 
 10 namespace fishingVesselUi
 11 {
 12     /// <summary>
 13     /// 正则表达式扩展文本框   ***20171018***
 14     /// ControlType        文本框需要验证的类型
 15     /// ControlTypeText        显示的文字(只读)
 16     /// IsNULL                 填写的内容是否可空
 17     /// IsPass                 格式是否正确(在文本框失去焦点时验证,只读)
 18     /// </summary>
 19     [System.Drawing.ToolboxBitmap(typeof(TextBox))]
 20     public partial class MyTextBox : TextBox
 21     {
 22         //水印
 23         private readonly Label lblwaterText = new Label();
 24         public MyTextBox()
 25         {
 26             InitializeComponent();
 27             #region 设置水印的样式
 28             lblwaterText.BorderStyle = BorderStyle.None;
 29             lblwaterText.Enabled = false;
 30             lblwaterText.BackColor = Color.White;
 31             lblwaterText.AutoSize = false;
 32             lblwaterText.Top = 1;
 33             lblwaterText.Left = 2;
 34             lblwaterText.FlatStyle = FlatStyle.System;
 35             Controls.Add(lblwaterText);
 36             #endregion
 37         }
 38 
 39         #region 文本框验证相关信息
 40         //类型枚举
 41         public enum RegexType
 42         {
 43             Custom,         //正常
 44             Number,         //数字 整数或者小数
 45             CNString,       //汉字
 46             Zip,            //邮政编码
 47             Email,          //电子邮箱
 48             Phone,          //手机号码     
 49             Integer,        //整数
 50             NInteger,       //负整数
 51             Float,          //浮点数
 52             ENChar,         //英文字符
 53             NumChar,        //数字和英文字母
 54             NumLineChar,    //数字、英文字母或下划线
 55             Url,
 56             QQ,
 57             DCard,          //身份证
 58             IP,
 59             DateTime,       //日期时间
 60             Date,           //日期
 61             Year,
 62             Month,
 63             Day,
 64             Time,
 65             Password,       //密码
 66             JobNum,         //工号
 67             Account,        //账号
 68             engineCoefficient,          //发动机调整系数
 69             environmentCoefficient,     //环境调整系数
 70             indeterminacyCoefficient,   //不确定因素的调整系数
 71         }
 72 
 73         #region 私有属性
 74         
 75         /// <summary>
 76         /// 文本框类型
 77         /// </summary>
 78         private RegexType _controlType;
 79         
 80         /// <summary>
 81         /// 显示的名称
 82         /// </summary>
 83         private string _controlTypeText = "默认";
 84         
 85         /// <summary>
 86         /// 是否可空 默认为可空
 87         /// </summary>
 88         private bool _isNULL = true;
 89 
 90         /// <summary>
 91         /// 验证是否通过
 92         /// </summary>
 93         private bool _isPass = false;
 94         #endregion
 95 
 96         #region Properties 属性栏添加的属性
 97 
 98         [DefaultValue(RegexType.Custom), Description("文本框类型")]
 99         public RegexType ControlType
100         {
101             get { return _controlType; }
102             set
103             {
104                 _controlType = value;
105                 //对应显示的文字
106                 this.ShowDescription(value);
107                 //重新绘制控件
108                 base.Invalidate();
109             }
110         }
111 
112         [DefaultValue("默认"), Description("控件验证描述")]
113         public string ControlTypeText
114         {
115             get { return _controlTypeText; }
116         }
117 
118         [DefaultValue(typeof(bool), "True"), Description("内容是否可空")]
119         public bool IsNULL
120         {
121             get { return _isNULL; }
122             set { _isNULL = value; base.Invalidate(); }
123         }
124         [DefaultValue(typeof(bool), "False"), Description("填写的内容格式是否正确,只读")]
125         public bool IsPass
126         {
127             get { return _isPass; }
128         }
129         #endregion
130         //判断验证类型
131         private void Testing(RegexType value, string text)
132         {
133             //可空 验证字符串为空
134             if (_isNULL && string.IsNullOrEmpty(text.Trim()))
135             {
136                 _isPass = true;
137                 return;
138             }
139             //不能为空 验证字符串为空
140             if (!_isNULL && string.IsNullOrEmpty(text))
141             {
142                 _isPass = false;
143                 return;
144             }
145             //其他的两种情况都需要正则验证
146             switch (value)
147             {
148                 case RegexType.Custom:
149                     _isPass = true;
150                     break;
151                 case RegexType.Account:
152                     _isPass = Proving(text, @"^[\\u4e00-\\u9fa5A-Za-z0-9-_]*$");
153                     break;
154                 case RegexType.Password:
155                     _isPass = Proving(text, @"^\\w{6,18}$");
156                     break;
157                 case RegexType.JobNum:
158                     _isPass = Proving(text, @"^[A-Za-z0-9]{10,15}$");
159                     break;
160                 case RegexType.engineCoefficient:
161                     _isPass = Proving(text, @"^([1-2]{1})(\\.\\d+)|(0\\.{1}[1-9]+)|(3(\\.0)?)$");
162                     break;
163                 case RegexType.environmentCoefficient:
164                     _isPass = Proving(text, @"^(1{1})(\\.[0-4]\\d*)+|(0\\.[5-9]\\d*)+|(1\\.5)?$");
165                     break;
166                 case RegexType.indeterminacyCoefficient:
167                     _isPass = Proving(text, @"^^(1{1})(\\.[0-4]\\d*)+|(0\\.{1}[1-9]\\d*)+|(1\\.5)?$");
168                     break;
169                 case RegexType.Number:
170                     _isPass = Proving(text, @"^-?[0-9]+\\.{0,1}[0-9]*$");
171                     break;
172                 case RegexType.CNString:
173                     _isPass = Proving(text, @"^[\\u4e00-\\u9fa5]*$");
174                     break;
175                 case RegexType.Zip:
176                     _isPass = Proving(text, @"^[1-9]\\d{5}$");
177                     break;
178                 case RegexType.Email:
179                     _isPass = Proving(text, @"^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
180                     break;
181                 case RegexType.Phone:
182                     _isPass = Proving(text, @"^1[2-8]{2}\\d{8}$");
183                     break;
184                 case RegexType.Integer:
185                     _isPass = Proving(text, @"^-?[1-9]\\d*$");
186                     break;
187                 case RegexType.NInteger:
188                     _isPass = Proving(text, @"^-[1-9]\\d*$");
189                     break;
190                 case RegexType.Float:
191                     _isPass = Proving(text, @"^(-?\\d+)(\\.\\d+)?$");
192                     break;
193                 case RegexType.ENChar:
194                     _isPass = Proving(text, @"^[A-Za-z]+$");
195                     break;
196                 case RegexType.NumChar:
197                    _isPass = Proving(text, @"^[A-Za-z0-9]+$");
198                     break;
199                 case RegexType.NumLineChar:
200                     _isPass = Proving(text, @"^[A-Za-z0-9_]+$");
201                     break;
202                 case RegexType.Url:
203                     _isPass = Proving(text, @"^http://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$");
204                     break;
205                 case RegexType.QQ:
206                     _isPass = Proving(text, @"^[1-9][0-9]{4,}$");
207                     break;
208                 case RegexType.DCard:
209                     _isPass = Proving(text, @"^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\\d{4}((19\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))|(19\\d{2}(0[13578]|1[02])31)|(19\\d{2}02(0[1-9]|1\\d|2[0-8]))|(19([13579][26]|[2468][048]|0[48])0229))\\d{3}(\\d|X|x)?$");
210                     break;
211                 case RegexType.IP:
212                     _isPass = Proving(text, @"^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$");
213                     break;
214                 case RegexType.DateTime:
215                     _isPass = Proving(text, @"^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$");
216                     break;
217                 case RegexType.Date:
218                     _isPass = Proving(text, @"^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
219                     break;
220                 case RegexType.Year:
221                     _isPass = Proving(text, @"^[1-9]\\d{3}$");
222                     break;
223                 case RegexType.Month:
224                     _isPass = Proving(text, @"^(0?[123456789]|1[012])$");
225                     break;
226                 case RegexType.Day:
227                     _isPass = Proving(text, @"^(0?[1-9]|[12]\\d|3[01])$");
228                     break;
229                 case RegexType.Time:
230                     _isPass = Proving(text, @"^(20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$");
231                     break;
232                 default:
233                     break;
234             }
235 
236         }
237         //格式是否正确
238         private bool Proving(string str, string regexStr)
239         {
240             bool result;
241             Regex regex;
242             try
243             {
244                 regex = new Regex(regexStr);
245             }
246             catch
247             {
248                 return false;
249             }
250             return result = regex.IsMatch(str);
251         }
252 
253         //验证类型的改变 对应改变显示的汉字
254         private void ShowDescription(RegexType value)
255         {
256             switch (value)
257             {
258                 case RegexType.Custom:
259                     this._controlTypeText = lblwaterText.Text = "默认";
260                     break;
261                 case RegexType.Account:
262                     this._controlTypeText = lblwaterText.Text = "中英文,数字,下划线和减号";
263                     break;
264                 case RegexType.Password:
265                     this._controlTypeText = lblwaterText.Text = "6-18位的数字、字母或下划线";
266                     break;
267                 case RegexType.JobNum:
268                     this._controlTypeText = lblwaterText.Text = "10-15位的数字或字母";
269                     break;
270                 case RegexType.engineCoefficient:
271                     this._controlTypeText = lblwaterText.Text = "取值0.1~3之间的小数";
272                     break;
273                 case RegexType.environmentCoefficient:
274                     this._controlTypeText = lblwaterText.Text = "取值0.5~1.5之间的小数";
275                     break;
276                 case RegexType.indeterminacyCoefficient:
277                     this._controlTypeText = lblwaterText.Text = "取值0.1~1.5之间的小数";
278                     break;
279                 case RegexType.Number:
280                     this._controlTypeText = lblwaterText.Text = "数字";
281                     break;
282                 case RegexType.CNString:
283                     this._controlTypeText = lblwaterText.Text = "汉字";
284                     break;
285                 case RegexType.Zip:
286                     this._controlTypeText = lblwaterText.Text = "邮政编码";
287                     break;
288                 case RegexType.Email:
289                     this._controlTypeText = lblwaterText.Text = "电子邮件";
290                     break;
291                 case RegexType.Phone:
292                     this._controlTypeText = lblwaterText.Text = "手机号";
293                     break;
294                 case RegexType.Integer:
295                     this._controlTypeText = lblwaterText.Text = "整数";
296                     break;
297                 case RegexType.NInteger:
298                     this._controlTypeText = lblwaterText.Text = "负整数";
299                     break;
300                 case RegexType.Float:
301                     this._controlTypeText = lblwaterText.Text = "小数";       //浮点数
302                     break;
303                 case RegexType.ENChar:
304                     this._controlTypeText = lblwaterText.Text = "英文字符";
305                     break;
306                 case RegexType.NumChar:
307                     this._controlTypeText = lblwaterText.Text = "数字和英文字母";
308                     break;
309                 case RegexType.NumLineChar:
310                     this._controlTypeText = lblwaterText.Text = "数字、英文字母或下划线";
311                     break;
312                 case RegexType.Url:
313                     this._controlTypeText = lblwaterText.Text = "URL";
314                     break;
315                 case RegexType.QQ:
316                     this._controlTypeText = lblwaterText.Text = "QQ";
317                     break;
318                 case RegexType.DCard:
319                     this._controlTypeText = lblwaterText.Text = "身份证";
320                     break;
321                 case RegexType.IP:
322                     this._controlTypeText = lblwaterText.Text = "IP";
323                     break;
324                 case RegexType.DateTime:
325                     this._controlTypeText = lblwaterText.Text = "年-月-日 时:分:秒";
326                     break;
327                 case RegexType.Date:
328                     this._controlTypeText = lblwaterText.Text = "年-月-日";
329                     break;
330                 case RegexType.Year:
331                     this._controlTypeText = lblwaterText.Text = "年份";
332                     break;
333                 case RegexType.Month:
334                     this._controlTypeText = lblwaterText.Text = "月份";
335                     break;
336                 case RegexType.Day:
337                     this._controlTypeText = lblwaterText.Text = "日期";
338                     break;
339                 case RegexType.Time:
340                     this._controlTypeText = lblwaterText.Text = "时:分:秒";
341                     break;
342             }
343         }
344         #endregion
345 
346         #region 添加文本框水印
347         /// <summary>
348         /// 水印 文本框为空时提示用户信息
349         /// </summary>
350         [Category("扩展属性"), Description("显示的提示信息")]
351         public string WaterText
352         {
353             get { return lblwaterText.Text; }
354             set { lblwaterText.Text = value; }
355         }
356 
357         public override string Text
358         {
359             set
360             {
361                 lblwaterText.Visible = value == string.Empty;
362                 base.Text = value;
363             }
364             get
365             {
366                 return base.Text;
367             }
368         }
369         #endregion
370 
371         #region 重写文本框控件的事件集
372         //重写了文本框的值发生改变事件
373         protected override void OnTextChanged(EventArgs e)
374         {
375             lblwaterText.Visible = base.Text == string.Empty;
376             Testing(this.ControlType, this.Text);
377             base.OnTextChanged(e);
378         }
379         //重写了文本框的大小发生改变事件
380         protected override void OnSizeChanged(EventArgs e)
381         {
382             if (Multiline && (ScrollBars == ScrollBars.Vertical || ScrollBars == ScrollBars.Both))
383                 lblwaterText.Width = Width - 20;
384             else
385                 lblwaterText.Width = Width;
386             lblwaterText.Height = Height - 2;
387             base.OnSizeChanged(e);
388         }
389         //重写了鼠标按下事件
390         protected override void OnMouseDown(MouseEventArgs e)
391         {
392             lblwaterText.Visible = false;
393             base.OnMouseDown(e);
394         }
395         //重写了鼠标离开事件
396         protected override void OnMouseLeave(EventArgs e)
397         {
398             lblwaterText.Visible = base.Text == string.Empty;
399             base.OnMouseLeave(e);
400         }
401 
402         //重写文本框的键盘按下事件(OnKeyPress)
403         //protected override void OnKeyPress(KeyPressEventArgs e)
404         //{
405         //    Testing(this.ControlType, this.Text);
406         //    base.OnLeave(e);
407         //    base.OnKeyPress(e);
408         //}
409 
410         //重写了文本框的失去焦点事件(OnLeave)  文本框改变事件(OnTextChanged)
411         protected override void OnLeave(EventArgs e)
412         {
413             if (IsPass == false)
414             {
415                 MessageBox.Show("输入有误", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
416                 this.Focus();
417             }
418             base.OnLeave(e);
419         }
420         #endregion
421     }
422 }
View Code

 

以上是关于winform,自定义文本框控件 实现文本框验证加水印功能的主要内容,如果未能解决你的问题,请参考以下文章

winform绘制自定义控件

VC++用户在文本框自定义快捷键

winform文本框控件输入错误时提示

WinForms 文本框的自定义插入符号

WPF 自定义控件将文本框文本重置为默认值

c# winform 如何取得用户控件中 的值