using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Text.RegularExpressions; using Mesnac.Controls.Base; namespace Mesnac.Controls.Default { [ToolboxBitmap(typeof(System.Windows.Forms.TextBox))] public partial class MCTextBox : TextBox, IBaseControl { public enum RegexType { 默认, 数字, 汉字, 邮政编码, Email, 座机电话号码, 中国电话号码, 电话号码, 整数, 负整数, 浮点类型, 非负浮点数, 正浮点数, 非正浮点数, 负浮点数, 英文字符, 大写英文字符, 小写英文字符, 数字和英文字母, 数字英文字母或下划线, Url, QQ, 身份证, IP, 日期类型, 日期, 年, 月, 日, 时间, 时间Am, 中文日期 } #region 命令 private const int WM_ERASEBKGND = 0x0014; private const int WM_PAINT = 0xF; private const uint WM_NCPAINT = 0x0085; #endregion #region 字段 private Color _borderColor = Color.FromArgb(107, 191, 111); private string _waterMarkText; private Color _waterMarkTextColor = Color.DarkGray; private float _borderWeight = 1; private RegexType _controlType = RegexType.默认; private string _controlTypeText = "默认"; private int _maxValue; private int _minValue; private bool _isEmpty = true;//允许 private bool _isValid = true;//保存有效性 private bool _mcVisible = true; //保存可见性 private bool _mcEnabled = true; //保存可用性 private Color r = Color.FromArgb(107, 191, 111); #endregion #region 属性 [Description("水印文字"), Category("Appearance")] public string WaterMarkText { get { return _waterMarkText; } set { _waterMarkText = value; base.Invalidate(); } } [DefaultValue(typeof(Color), "DarkGray"), Description("水印文字颜色"), Category("Appearance")] public Color WaterMarkTextColor { get { return _waterMarkTextColor; } set { _waterMarkTextColor = value; base.Invalidate(); } } [DefaultValue(typeof(Color), "107, 191, 111"), Description("边框颜色"), Category("Appearance")] public Color BorderColor { get { return _borderColor; } set { _borderColor = value; base.Invalidate(); } } [DefaultValue(typeof(float), "1"), Description("边框粗细"), Category("Appearance")] public float BorderWeight { get { return _borderWeight; } set { _borderWeight = value; base.Invalidate(); } } [DefaultValue(RegexType.默认), Description("文本框类型"), Category("Appearance")] public RegexType ControlType { get { return _controlType; } set { _controlType = value; this.ShowDescription(value); base.Invalidate(); } } [DefaultValue("默认"), Description("控件验证描述"), Category("Behavior")] public string ControlTypeText { get { return _controlTypeText; } } [DefaultValue(null), Description("最大值"), Category("Data")] public int MaxValue { get { return _maxValue; } set { _maxValue = value; } } [DefaultValue(null), Description("最小值"), Category("Data")] public int MinValue { get { return _minValue; } set { _minValue = value; } } [DefaultValue(true), Description("验证是否通过"), Category("Behavior")] public bool InvalidPass { get { return _isValid; } } [Description("是否允许为空"), Category("Behavior")] public bool IsEmpty { get { return _isEmpty; } set { _isEmpty = value; } } #endregion public MCTextBox() { InitializeComponent(); } public MCTextBox(IContainer container) { container.Add(this); InitializeComponent(); } protected override Control.ControlCollection CreateControlsInstance() { r = this.BorderColor; this.BorderStyle = BorderStyle.FixedSingle; return base.CreateControlsInstance(); } #region 事件 private List _keyDownActionList = new List(); public List KeyDownActionList { get { return _keyDownActionList; } set { _keyDownActionList = value; } } #endregion #region 验证 private void ShowDescription(RegexType value) { switch (value) { case RegexType.默认: this._controlTypeText = "默认"; break; case RegexType.数字: this._controlTypeText = "数字"; break; case RegexType.汉字: this._controlTypeText = "汉字"; break; case RegexType.邮政编码: this._controlTypeText = "邮政编码"; break; case RegexType.Email: this._controlTypeText = "电子邮件"; break; case RegexType.座机电话号码: this._controlTypeText = "座机电话号码"; break; case RegexType.中国电话号码: this._controlTypeText = "中国电话号码"; break; case RegexType.电话号码: this._controlTypeText = "手机号码"; break; case RegexType.整数: this._controlTypeText = "整数"; break; case RegexType.负整数: this._controlTypeText = "负整数"; break; case RegexType.浮点类型: this._controlTypeText = "浮点数"; break; case RegexType.非负浮点数: this._controlTypeText = "非负浮点数"; break; case RegexType.正浮点数: this._controlTypeText = "正浮点数"; break; case RegexType.非正浮点数: this._controlTypeText = "非正浮点数"; break; case RegexType.负浮点数: this._controlTypeText = "负浮点数"; break; case RegexType.英文字符: this._controlTypeText = "英文字符"; break; case RegexType.大写英文字符: this._controlTypeText = "大写英文字符"; break; case RegexType.小写英文字符: this._controlTypeText = "小写英文字符"; break; case RegexType.数字和英文字母: this._controlTypeText = "数字和英文字母"; break; case RegexType.数字英文字母或下划线: this._controlTypeText = "数字、英文字母或下划线"; break; case RegexType.Url: this._controlTypeText = "URL"; break; case RegexType.QQ: this._controlTypeText = "QQ"; break; case RegexType.身份证: this._controlTypeText = "身份证"; break; case RegexType.IP: this._controlTypeText = "IP"; break; case RegexType.日期类型: this._controlTypeText = "2000-2-28 23:29:59"; break; case RegexType.日期: this._controlTypeText = "2000-2-28"; break; case RegexType.年: this._controlTypeText = "年份"; break; case RegexType.月: this._controlTypeText = "月份"; break; case RegexType.日: this._controlTypeText = "日"; break; case RegexType.时间: this._controlTypeText = "23:29:59"; break; case RegexType.时间Am: this._controlTypeText = "2000-02-29 10:29:39 pm"; break; case RegexType.中文日期: this._controlTypeText = "2009年2月28日"; break; } } protected override void OnTextChanged(System.EventArgs e) { bool b = Invalid(this.ControlType, this.Text); if (!b) { this.BorderColor = Color.Red; this.errorProvider1.SetIconAlignment((Control)this, ErrorIconAlignment.MiddleRight); this.errorProvider1.SetError((Control)this, _waterMarkText == null ? _controlTypeText : _waterMarkText); this._isValid = false; //this.errorProvider1.Tag = false; } else { this.BorderColor = r; errorProvider1.SetError((Control)this, ""); this._isValid = true; //this.errorProvider1.Tag = true; base.Invalidate(); } base.Invalidate(); } protected override void OnLostFocus(EventArgs e) { if (!this._isValid) { return; } //WmPaint(); if (!_isEmpty) { if (this.Text == string.Empty) { this.BorderColor = Color.Red; using (Graphics g = Graphics.FromHwnd(this.Handle)) { using (Pen pen = new Pen(this.BorderColor, this.BorderWeight)) { g.DrawRectangle(pen, 0, 0, Size.Width - 1, Size.Height - 1); } } this._isValid = false; errorProvider1.SetIconAlignment((Control)this, ErrorIconAlignment.MiddleRight); errorProvider1.SetError((Control)this, "不允许为空!"); return; } else { errorProvider1.SetIconAlignment((Control)this, ErrorIconAlignment.MiddleRight); errorProvider1.SetError((Control)this, ""); this._isValid = true; } } if (!Invalid(this.ControlType)) { this.BorderColor = Color.Red; this._isValid = false; errorProvider1.SetIconAlignment((Control)this, ErrorIconAlignment.MiddleRight); errorProvider1.SetError((Control)this, "数值超出指定范围!"); } else { this.BorderColor = r; this._isValid = true; errorProvider1.SetError((Control)this, ""); base.Invalidate(); } base.Invalidate(); base.OnLostFocus(e); } private bool Invalid(RegexType value) { if (this._isEmpty && String.IsNullOrEmpty(this.Text)) { return true; } bool b = true; switch (value) { case RegexType.整数: if (Convert.ToInt32(this._maxValue) >= Convert.ToInt32(this.Text) && Convert.ToInt32(this._minValue) <= Convert.ToInt32(this.Text)) b = true; else b = false; break; case RegexType.负整数: if (Convert.ToInt32(this._maxValue) >= Convert.ToInt32(this.Text) && Convert.ToInt32(this._minValue) <= Convert.ToInt32(this.Text)) b = true; else b = false; break; case RegexType.浮点类型: if (Convert.ToDecimal(this._maxValue) >= Convert.ToDecimal(this.Text) && Convert.ToDecimal(this._minValue) <= Convert.ToDecimal(this.Text)) b = true; else b = false; break; case RegexType.非负浮点数: if (Convert.ToDecimal(this._maxValue) >= Convert.ToDecimal(this.Text) && Convert.ToDecimal(this._minValue) <= Convert.ToDecimal(this.Text)) b = true; else b = false; break; case RegexType.正浮点数: if (Convert.ToDecimal(this._maxValue) >= Convert.ToDecimal(this.Text) && Convert.ToDecimal(this._minValue) <= Convert.ToDecimal(this.Text)) b = true; else b = false; break; case RegexType.非正浮点数: if (Convert.ToDecimal(this._maxValue) >= Convert.ToDecimal(this.Text) && Convert.ToDecimal(this._minValue) <= Convert.ToDecimal(this.Text)) b = true; else b = false; break; default: break; } return b; } private bool Invalid(RegexType value, string text) { if (_isEmpty) { if (this.Text == string.Empty) return true; } bool b = false; switch (value) { case RegexType.默认: b = true; break; case RegexType.数字: b = Validation(text, @"^\d+$"); break; case RegexType.汉字: b = Validation(text, @"^[\u4e00-\u9fa5]$"); break; case RegexType.邮政编码: b = Validation(text, @"^[1-9]\d{5}$"); break; case RegexType.Email: b = Validation(text, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"); break; case RegexType.座机电话号码: b = Validation(text, @"^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$"); break; case RegexType.中国电话号码: b = Validation(text, @"^\d{3}-\d{8}|\d{4}-\d{7}$"); break; case RegexType.电话号码: b = Validation(text, @"^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$"); break; case RegexType.整数: b = Validation(text, @"^-?\d+$"); break; case RegexType.负整数: b = Validation(text, @"^-[0-9]*[1-9][0-9]*$"); break; case RegexType.浮点类型: b = Validation(text, @"^(-?\d+)(\.\d+)?$"); break; case RegexType.非负浮点数: b = Validation(text, @"^\d+(\.\d+)?$"); break; case RegexType.正浮点数: b = Validation(text, @"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"); break; case RegexType.非正浮点数: b = Validation(text, @"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"); break; case RegexType.负浮点数: b = Validation(text, @"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"); break; case RegexType.英文字符: b = Validation(text, @"^[A-Za-z]+$"); break; case RegexType.大写英文字符: b = Validation(text, @"^[A-Z]+$"); break; case RegexType.小写英文字符: b = Validation(text, @"^[a-z]+$"); break; case RegexType.数字和英文字母: b = Validation(text, @"^[A-Za-z0-9]+$"); break; case RegexType.数字英文字母或下划线: b = Validation(text, @"^\w+$"); break; case RegexType.Url: b = Validation(text, @"^(?:https?|ftp)\:\/\/(?:(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=:]|%[0-9a-f]{2,2})*\@)?(?:((?:(?:[a-z0-9][a-z0-9\-]*[a-z0-9]|[a-z0-9])\.)*(?:[a-z][a-z0-9\-]*[a-z0-9]|[a-z])|(?:\[[^\]]*\]))(?:\:[0-9]*)?)(?:\/(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@]|%[0-9a-f]{2,2})*)*(?:\?(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?(?:\#(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?$"); break; case RegexType.QQ: b = Validation(text, @"^[1-9][0-9]{4,}$"); break; case RegexType.身份证: b = Validation(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)?$"); break; case RegexType.IP: b = Validation(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])$"); break; case RegexType.日期类型: b = Validation(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$"); break; case RegexType.日期: b = Validation(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-))$"); break; case RegexType.年: b = Validation(text, @"^((1[6-9]|[2-9]\d)\d{2})$"); break; case RegexType.月: b = Validation(text, @"^(0?[123456789]|1[012])$"); break; case RegexType.日: b = Validation(text, @"^(0?[1-9]|[12]\d|3[01])$"); break; case RegexType.时间: b = Validation(text, @"^(20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$"); break; case RegexType.时间Am: b = Validation(text, @"^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$"); break; case RegexType.中文日期: b = Validation(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日))$"); break; } return b; } private bool Validation(string validValue, string regularExpression) { Regex regex; try { regex = new Regex(regularExpression); } catch { return false; } if (regex.IsMatch(validValue)) { return true; } else { return false; } } protected override void OnPaint(PaintEventArgs pe) { this.BorderStyle = BorderStyle.FixedSingle; //if (m.Msg == WM_PAINT || m.Msg == WM_NCPAINT) //{ if (this.BorderWeight % 2 == 0) { this.BorderWeight -= 1; } using (Graphics g = Graphics.FromHwnd(this.Handle)) { using (Pen pen = new Pen(this.BorderColor, this.BorderWeight)) { g.DrawRectangle(pen, 0, 0, Size.Width - 1, Size.Height - 1); } } WmPaint(); //} base.OnPaint(pe); } private void WmPaint() { using (Graphics graphics = Graphics.FromHwnd(base.Handle)) { if (Text.Length == 0 && !string.IsNullOrEmpty(_waterMarkText) && !Focused) { TextFormatFlags format = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter; if (RightToLeft == RightToLeft.Yes) { format |= TextFormatFlags.RightToLeft | TextFormatFlags.Right; } TextRenderer.DrawText(graphics, _waterMarkText, Font, base.ClientRectangle, _waterMarkTextColor, format); } } } #endregion #region 接口实现 public string MCKey { get; set; } public object MCValue { get { return this.Text; } set { this.Text = value == null ? string.Empty : value.ToString(); } } public IBaseControl MCRoot { get { return null; } set { ; } } [TypeConverter(typeof(DataSourceConverter))] [Description("数据连接"), Category("数据")] public string MCDataSourceID { get; set; } public MCDataSource MCDataSource { get; set; } [Description("是否为数据库控件"), Category("数据")] public bool IsDbControl { get; set; } [Description("初始化SQL"), Category("数据")] public string InitDataSource { get; set; } [Description("执行SQL"), Category("数据")] public string ActionDataSource { get; set; } [Description("绑定数据源"), Category("数据")] public object BindDataSource { get; set; } [Description("操作类型"), Category("数据")] public DbOptionTypes DbOptionType { get; set; } [Description("是否可见"), Category("行为")] public bool MCVisible { get { return this._mcVisible; } set { this._mcVisible = value == null ? true : value; if (this.Site.DesignMode) { this.Visible = true; } else { this.Visible = this._mcVisible; } } } [Description("是否可用"), Category("行为")] public bool MCEnabled { get { return this._mcEnabled; } set { this._mcEnabled = value == null ? true : value; if (this.Site.DesignMode) { this.Enabled = true; } else { this.Enabled = this._mcEnabled; } } } public bool IsValid { get { return _isValid; } set { _isValid = value; } } #endregion } }