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