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 ///
13 /// 正则表达式扩展文本框 ***20171018***
14 /// ControlType 文本框需要验证的类型
15 /// ControlTypeText 显示的文字(只读)
16 /// IsNULL 填写的内容是否可空
17 /// IsPass 格式是否正确(在文本框失去焦点时验证,只读)
18 ///
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 ///
76 /// 文本框类型
77 ///
78 private RegexType _controlType;
79
80 ///
81 /// 显示的名称
82 ///
83 private string _controlTypeText = "默认";
84
85 ///
86 /// 是否可空 默认为可空
87 ///
88 private bool _isNULL = true;
89
90 ///
91 /// 验证是否通过
92 ///
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 ///
348 /// 水印 文本框为空时提示用户信息
349 ///
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 }