using System; using System.ComponentModel; using System.Drawing; using System.Globalization; using System.Text.RegularExpressions; using System.Windows.Forms; using Dongke.WinForm.Utilities; namespace Dongke.WinForm.Controls { /// /// 数值输入文本框 /// public abstract class TextBoxNumerical : TextBox, IDKControl, IDataVerifiable, IAsyncControl { #region 常量 /// /// [^0-9] /// private const string REJECT_CHARS = "[^0-9]"; /// /// [^-.0-9] /// private const string REJECT_CHARS_ALL = "[^-.0-9]"; /// /// [-.] /// private const string REJECT_CHARS_NP = "-."; /// /// [#,##] /// private const string COMMA_HAS = "#,##"; /// /// [####] /// private const string COMMA_NOT = "####"; #endregion #region 事件声明 /* #region TextPaste /// /// 当输入文本粘贴后发生 /// private static readonly object EventTextPaste = new object(); /// /// TextPaste 事件 /// public event TextPasteEventHandler TextPaste { add { base.Events.AddHandler(EventTextPaste, value); } remove { base.Events.RemoveHandler(EventTextPaste, value); } } #endregion */ #region HasErrorChanged /// /// 当 HasError 属性的值更改时发生。 /// private static readonly object EventHasErrorChanged = new object(); /// /// 当 HasError 属性的值更改时发生。 /// [Description("当 HasError 属性的值更改时发生。"), Category("CustomerEx")] public event EventHandler HasErrorChanged { add { base.Events.AddHandler(EventHasErrorChanged, value); } remove { base.Events.RemoveHandler(EventHasErrorChanged, value); } } #endregion #endregion #region 成员变量 /// /// 验证不通过,焦点不离开 /// private bool _validatingCancel = false; /// /// 焦点是否进入控件 /// private bool _entered = false; /// /// 鼠标是否进入控件 /// private bool _mouseOver = false; /// /// 边框颜色 /// private Color? _borderColor = null; /// /// 控件在获得焦点时,文本内容的选择方式。 /// private EnteredSelectTextStyle _enteredSelectTextStyle = EnteredSelectTextStyle.None; /// /// 数值精度 /// //private DNumber _number = DNumber.Empty; private Point _number = Point.Empty; /// /// 输入最大值 /// private decimal _maxValue = 70000000000000000000000000000m; /// /// 输入最小值 /// private decimal _minValue = -70000000000000000000000000000m; /// /// 数值精度最大值 /// private decimal _maxDNumberValue = decimal.MaxValue; /// /// 数值精度最小值 /// private decimal _minDNumberValue = decimal.MinValue; /// /// 最大值 /// private decimal _maxNumberValue = decimal.MaxValue; /// /// 最小值 /// private decimal _minNumberValue = decimal.MinValue; /// /// 数值 /// protected decimal? _dataValue = null; /// /// 允许负数 /// private bool _allowNegative = true; /// /// 是否显示千分隔符(逗号) /// private ShowDigitalKind _thousandsSeparator = ShowDigitalKind.Always; /// /// 补齐小数位数 /// private ShowDigitalKind _showDecimalPlaces = ShowDigitalKind.Always; /// /// 限制数值输入方式 /// private LimitInputKind _limitInputKind = LimitInputKind.None; /// /// 正在设置文本 /// private bool _isSettingText = false; #endregion #region 构造函数 /// /// 数值输入文本框 /// public TextBoxNumerical() { base.TextAlign = HorizontalAlignment.Right; base.ImeMode = ImeMode.Off; CommonSetting.InitControls(this); } #endregion #region 属性 /// /// 获取一个值,该值指示控件是否有输入焦点。 /// [DefaultValue(false)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public virtual bool Entered { get { return this._entered; } protected set { if (this._entered != value) { this._entered = value; this.InvalidateBorder(); } } } /// /// 获取一个值,该值指示鼠标是否在控件上方。 /// [DefaultValue(false)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public virtual bool MouseOver { get { return this._mouseOver; } protected set { if (this._mouseOver != value) { this._mouseOver = value; this.InvalidateBorder(); } } } /// /// 获取或设置数字的精度,DNumber.X为整数位的有效位数,DNumber.Y为小数位的有效位数 /// [Description("获取或设置数字的精度,DNumber.X为整数位的有效位数,DNumber.Y为小数位的有效位数"), Category("CustomerEx")] [DefaultValue(typeof(Point), "0, 0")] public virtual Point Number { get { return this._number; } set { if (this._number != value) { this._number = value; this.SetDNumberValue(); this.SetTextValue(); } } } /// /// 获取或设置允许输入的数字最大值 /// [Description("获取或设置允许输入的数字最大值"), Category("CustomerEx")] //[DefaultValue(typeof(decimal), "79228162514264337593543950335")] [DefaultValue(typeof(decimal), "70000000000000000000000000000")] [Localizable(true)] public virtual decimal MaxValue { get { return this._maxValue; } set { if (value < this._minValue) { return; } if (this._maxValue != value) { this._maxValue = value; if (this.SetMaxOrMinValue()) { this.SetTextValue(); } } } } /// /// 获取或设置允许输入的数字最小值 /// [Description("获取或设置允许输入的数字最小值"), Category("CustomerEx")] //[DefaultValue(typeof(decimal), "-79228162514264337593543950335")] [DefaultValue(typeof(decimal), "-70000000000000000000000000000")] [Localizable(true)] public virtual decimal MinValue { get { return this._minValue; } set { if (value > this._maxValue) { return; } if (this._minValue != value) { this._minValue = value; if (this.SetMaxOrMinValue()) { this.SetTextValue(); } } } } /// /// 获取或设置文本框的数值 /// [Description("获取或设置文本框的数值"), Category("CustomerEx")] [DefaultValue(null)] public decimal? DataValue { get { return this._dataValue; } set { if (this._dataValue != value) { //this._dataValue = value; this.SetTextValue(value.HasValue ? value.ToString() : string.Empty); } } } /// /// 获取或设置是否允许输入负数 /// [Description("获取或设置是否允许输入负数"), Category("CustomerEx")] [DefaultValue(true)] public virtual bool AllowNegative { get { return this._allowNegative; } set { if (this._allowNegative != value) { this._allowNegative = value; bool needReset = this.SetDNumberValue(); //needReset = this.SetRejectedChars() || needReset; if (needReset) { this.SetTextValue(); } } } } /// /// 获取或设置一个值,该值指示如何显示千位分隔符(逗号)。 /// [Description("获取或设置一个值,该值指示如何显示千位分隔符(逗号)。"), Category("CustomerEx")] [DefaultValue(typeof(ShowDigitalKind), "Always")] public virtual ShowDigitalKind ThousandsSeparator { get { return this._thousandsSeparator; } set { if (!Enum.IsDefined(typeof(ShowDigitalKind), value)) { return; } if (this._thousandsSeparator != value) { this._thousandsSeparator = value; this.SetTextValue(); } } } /// /// 获取或设置一个值,该值指示如何显示小数位数。 /// [Description("获取或设置一个值,该值指示如何显示小数位数。"), Category("CustomerEx")] [DefaultValue(typeof(ShowDigitalKind), "Always")] public virtual ShowDigitalKind ShowDecimalPlaces { get { return this._showDecimalPlaces; } set { if (!Enum.IsDefined(typeof(ShowDigitalKind), value)) { return; } if (this._showDecimalPlaces != value) { this._showDecimalPlaces = value; this.SetTextValue(); } } } /// /// 获取或设置输入限制种类 /// [Description("获取或设置输入限制种类"), Category("CustomerEx")] [DefaultValue(typeof(LimitInputKind), "None")] public virtual LimitInputKind LimitInputKind { get { return this._limitInputKind; } set { if (!Enum.IsDefined(typeof(LimitInputKind), value)) { return; } if (this._limitInputKind != value) { this._limitInputKind = value; this.SetTextValue(); } } } #endregion #region 重写属性 /// /// 获取或设置在 System.Windows.Forms.TextBox.AutoCompleteSource 属性设置为 CustomSource /// 时使用的自定义 System.Collections.Specialized.StringCollection。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new AutoCompleteStringCollection AutoCompleteCustomSource { get { return base.AutoCompleteCustomSource; } set { base.AutoCompleteCustomSource = value; } } /// /// 获取或设置控制自动完成如何作用于 System.Windows.Forms.TextBox 的选项。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new AutoCompleteMode AutoCompleteMode { get { return base.AutoCompleteMode; } set { base.AutoCompleteMode = value; } } /// /// 获取或设置一个值,该值指定用于自动完成的完整字符串源。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new AutoCompleteSource AutoCompleteSource { get { return base.AutoCompleteSource; } set { base.AutoCompleteSource = value; } } /// /// 获取或设置 System.Windows.Forms.TextBox 控件是否在字符键入时修改其大小写格式。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new CharacterCasing CharacterCasing { get { return base.CharacterCasing; } set { base.CharacterCasing = value; } } /// /// 获取或设置一个值,该值指示此控件是否为多行控件。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool Multiline { get { return base.Multiline; } set { base.Multiline = value; } } /// /// 获取或设置控件中文本的对齐方式。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new HorizontalAlignment TextAlign { get { return base.TextAlign; } set { base.TextAlign = value; } } /// /// 获取或设置控件的输入法编辑器 (IME) 模式。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new ImeMode ImeMode { get { return base.ImeMode; } set { base.ImeMode = value; } } /// /// 获取一个用以指示是否可以将 System.Windows.Forms.Control.ImeMode 属性设置为活动值的值,以启用 IME 支持。 /// protected override bool CanEnableIme { get { return false; } } /// /// 获取或设置用户可在文本框控件中键入或粘贴的最大字符数 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override int MaxLength { get { return base.MaxLength; } set { base.MaxLength = value; } } /// /// 获取或设置当前文本。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override string Text { get { return base.Text; } set { this.SetTextValue(value); } } /// /// 获取或设置一个值,该值指示控件中当前选定的文本。 /// public override string SelectedText { get { return base.SelectedText; } set { this.PasteChars(value); } } /// /// 获取或设置字符,该字符用于屏蔽单行控件中的密码字符。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new char PasswordChar { get { return base.PasswordChar; } set { base.PasswordChar = value; } } /// /// 获取或设置哪些滚动条应出现在多行 System.Windows.Forms.TextBox 控件中。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new ScrollBars ScrollBars { get { return base.ScrollBars; } set { base.ScrollBars = value; } } /// /// 获取或设置一个值,该值指示 System.Windows.Forms.TextBox 控件中的文本是否应该以默认的密码字符显示。 /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new bool UseSystemPasswordChar { get { return base.UseSystemPasswordChar; } set { base.UseSystemPasswordChar = value; } } #endregion #region 重写事件 #region 属性改变 /// /// 引发 HasErrorChanged 事件 /// /// 包含事件数据的 EventArgs protected virtual void OnHasErrorChanged(EventArgs e) { EventHandler eventHandler = (EventHandler)base.Events[EventHasErrorChanged]; if (eventHandler != null) { eventHandler(this, e); } } /// /// 文本改变事件 /// /// protected override void OnTextChanged(EventArgs e) { if (!this._isSettingText) { this.SetTextValue(); return; } this._isSettingText = false; base.OnTextChanged(EventArgs.Empty); // TODO 实时验证? if (true) { this.ValidateData(); } } #endregion #region 行为事件 /// /// 引发 TextPaste 事件 /// /// 包含事件数据的 TextPasteEventArgs protected virtual void OnPaste(TextPasteEventArgs e) { //TextPasteEventHandler eventHandler = (TextPasteEventHandler)base.Events[EventTextPaste]; //if (eventHandler != null) //{ // eventHandler(this, e); //} } #endregion #region 键盘事件 /// /// 键盘输入 /// /// protected override void OnKeyPress(KeyPressEventArgs e) { base.OnKeyPress(e); if (e.Handled) { return; } if (!this.Enabled || this.ReadOnly || char.IsControl(e.KeyChar)) { // Back if (e.KeyChar == (char)8) { int ss = base.SelectionStart; int sl = base.SelectionLength; int tl = base.TextLength; if (ss == 0 || (ss == 1 && tl == 1) || sl == tl) { return; } e.Handled = true; } return; } if (!this.PressChar(e.KeyChar)) { WindowsAPI.MessageBeep(BeepType.MB_OK); } e.Handled = true; return; } /// /// 键盘点击 /// /// protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.Handled) { return; } if (e.KeyCode != Keys.Back && e.KeyCode != Keys.Delete) { return; } int ss = base.SelectionStart; int sl = base.SelectionLength; int tl = base.TextLength; #region Back if (e.KeyCode == Keys.Back) { // 删除空白 if (ss == 0 || (ss == 1 && tl == 1) || sl == tl) { return; } this.BackChars(); e.Handled = true; return; } #endregion #region Delete if (e.KeyCode == Keys.Delete) { // 删除空白 if (ss == tl || (ss == 0 && tl == 1) || sl == tl) { return; } this.DeleteChars(); e.Handled = true; return; } #endregion } #endregion #region 焦点事件 /// /// 输入焦点进入控件 /// /// protected override void OnEnter(EventArgs e) { this.Entered = true; base.OnEnter(e); } /// /// 获得焦点 /// /// protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); if (this._validatingCancel) { this._validatingCancel = false; return; } // 格式化显示文本 if (this._showDecimalPlaces != ShowDigitalKind.Always || this._thousandsSeparator != ShowDigitalKind.Always) { this.SetText(this.FormatText(base.Text)); } //this.SelectAll(); int textLength = base.Text.Length; if (textLength > 0) { switch (this._enteredSelectTextStyle) { case EnteredSelectTextStyle.Left: this.Select(0, 0); break; case EnteredSelectTextStyle.Right: this.Select(textLength, 0); break; case EnteredSelectTextStyle.All: this.SelectAll(); break; default: break; } } } /// /// 失去焦点 /// /// protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); } /// /// 输入焦点离开控件 /// /// protected override void OnLeave(EventArgs e) { base.OnLeave(e); //this.Entered = false; } /// /// 控件正在验证 /// /// protected override void OnValidating(CancelEventArgs e) { base.OnValidating(e); if (this.HasError && !this._canLostFocusOnError) { e.Cancel = true; } this._validatingCancel = e.Cancel; } /// /// 控件完成验证 /// /// protected override void OnValidated(EventArgs e) { this.Entered = false; this.SetText(this.FormatText(base.Text)); this._validatingCancel = false; base.OnValidated(e); } #endregion #region 鼠标事件 /// /// 鼠标进入控件 /// /// protected override void OnMouseEnter(EventArgs e) { this.MouseOver = true; base.OnMouseEnter(e); } /// /// 鼠标离开控件 /// /// protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); this.MouseOver = false; } /// /// 鼠标移动 /// /// protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); } /// /// 鼠标按下 /// /// protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); } /// /// 鼠标抬起 /// /// protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); } #endregion #endregion #region 重写方法 /// /// 处理 Windows 消息 /// /// 要处理的 Windows System.Windows.Forms.Message protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)WindowsMessage.WM_PASTE: // 粘贴 this.PasteChars(); return; case (int)WindowsMessage.WM_CUT: // 右键菜单 剪切 this.CutChars(); break; case (int)WindowsMessage.WM_CHAR: if (m.WParam.ToInt32() == 18) { // Ctrl + X 18 this.CutChars(); } break; default: break; } base.WndProc(ref m); if ((int)m.Result == 1) { // 剪切、back、delete 等操作没有改变Text时,设置 _isSettingText = false。 switch (m.Msg) { //case (int)WindowsMessage.WM_CUT: //// 剪切空白 case (int)WindowsMessage.WM_CHAR: // 输入达到最大长度,back 8 this._isSettingText = false; break; case (int)WindowsMessage.WM_KEYDOWN: //if (m.WParam.ToInt32() == 46) //{ // // delete 46 // this._isSettingText = false; //} break; default: break; } } if (m.Msg == (int)WindowsMessage.WM_PAINT || m.Msg == (int)WindowsMessage.WM_NCPAINT || m.Msg == (int)WindowsMessage.WM_CTLCOLOREDIT) { BorderColorPaint.WmBorderPaint(this._borderColor, this.Width, this.Height, ref m); } } #endregion #region 公有方法 #endregion #region 保护方法 #endregion #region 私有方法 /// /// 设置文本(过滤限制输入字符,并验证是否符合正则表达式) /// private void SetTextValue() { this.SetTextValue(base.Text); } /// /// 设置文本(过滤限制输入字符,并验证是否符合正则表达式) /// /// 文本 private void SetTextValue(string text) { text = this.RejectChars(ref text, string.Empty); text = this.FormatText(text); this.SetText(text); } /// /// 设置文本(修改base.Text属性) /// /// 文本 private void SetText(string text) { if (base.Text != text) { this._isSettingText = true; base.Text = text; this._isSettingText = false; } } /// /// Delete删除文本 /// private void DeleteChars() { // 原文本 string baseText = base.Text; // 选定的文本 string seletedText = base.SelectedText; // 选定文本起始位置 int selectionStart = base.SelectionStart; // 选定文本长度 int selectionLength = base.SelectionLength; // 删除的文本 string removedText = seletedText; // 输入后选定文本起始位置 int start = selectionStart + 1; if (selectionLength == 0) { removedText = baseText.Substring(selectionStart, 1); } // 删除字符为千分符【,】时,文本不变,输入焦点后移一位。 if (Constant.S_COMMA == removedText) { this.Select(start, 0); return; } // 删除字符为小数点【.】时,如果只有【.】或不补齐小数位数时,删除字符;其他情况不删除,输入焦点后移一位。 if (baseText.Length > 1 && this._showDecimalPlaces == ShowDigitalKind.Always && Constant.S_POINT == removedText) { this.Select(start, 0); return; } // 新文本 string text = null; // 去掉选定的字符 if (selectionLength > 0) { text = baseText.Remove(selectionStart, selectionLength); } else { text = baseText.Remove(selectionStart, 1); } text = text.Replace(Constant.S_COMMA, string.Empty); // 验证输入后字符 if (this.CheckInputedText(text)) { // 格式化输入后字符 text = this.FormatText(text); // 输入后光标位置 start = this.GetDeleteSelectionStart(baseText, selectionStart, selectionLength, removedText, text); // 设置文本 if (baseText != text) { this._isSettingText = true; base.Text = text; this._isSettingText = false; } } // 设置输入光标 if (base.SelectionStart != start || selectionLength > 0) { this.Select(start, 0); } } /// /// Back删除文本 /// private void BackChars() { // 原文本 string baseText = base.Text; // 选定的文本 string seletedText = base.SelectedText; // 选定文本起始位置 int selectionStart = base.SelectionStart; // 选定文本长度 int selectionLength = base.SelectionLength; // 删除的文本 string removedText = seletedText; // 输入后选定文本起始位置 int start = selectionStart; if (selectionLength == 0) { start = selectionStart - 1; removedText = baseText.Substring(start, 1); } // 删除字符为千分符【,】时,文本不变,输入焦点前移一位。 if (Constant.S_COMMA == removedText) { this.Select(start, 0); return; } // 删除字符为小数点【.】时,如果只有【.】或不补齐小数位数时,删除字符;其他情况不删除,输入焦点前移一位。 if (baseText.Length > 1 && this._showDecimalPlaces == ShowDigitalKind.Always && Constant.S_POINT == removedText) { this.Select(start, 0); return; } // 新文本 string text = null; // 去掉选定的字符 if (selectionLength > 0) { text = baseText.Remove(selectionStart, selectionLength); } else { text = baseText.Remove(start, 1); } text = text.Replace(Constant.S_COMMA, string.Empty); // 验证输入后字符 if (this.CheckInputedText(text)) { // 格式化输入后字符 text = this.FormatText(text); // 输入后光标位置 start = this.GetBackSelectionStart(baseText, selectionStart, selectionLength, removedText, text); // 设置文本 if (baseText != text) { this._isSettingText = true; base.Text = text; this._isSettingText = false; } } // 设置输入光标 if (base.SelectionStart != start || selectionLength > 0) { this.Select(start, 0); } } /// /// 剪切文本 /// private void CutChars() { if (!this.Enabled || this.ReadOnly) { return; } if (base.SelectionLength == 0) { return; } // 复制到剪切板 Clipboard.SetText(base.SelectedText); this.DeleteChars(); } /// /// 输入字符串 /// /// /// private bool PressChar(char key) { // 原文本 string baseText = base.Text; // 选定的文本 string seletedText = base.SelectedText; // 选定文本起始位置 int selectionStart = base.SelectionStart; // 选定文本长度 int selectionLength = base.SelectionLength; // 输入后选定文本起始位置 int start = selectionStart + selectionLength; if (selectionLength == 1 && seletedText[0] == key) { this.Select(start, 0); return true; } if (selectionLength == 2 && ((seletedText[0] == Constant.C_COMMA && seletedText[1] == key) || (seletedText[0] == key && seletedText[1] == Constant.C_COMMA))) { this.Select(start, 0); return true; } if (key == Constant.C_POINT) { if (this._number.Y > 0) { int indexPoint = baseText.IndexOf(Constant.C_POINT); if (selectionLength == 0 && indexPoint == selectionStart) { this.Select(start + 1, 0); return true; } } else { return false; } } string chars = key.ToString(); string text = this.RejectChars(ref chars, baseText, selectionStart, selectionLength); if (this.CheckInputedText(text)) { text = this.FormatText(text); // 输入后光标位置 start = this.GetKeySelectionStart(baseText, selectionStart, selectionLength, seletedText, text, chars); // 设置文本 if (baseText != text) { this._isSettingText = true; base.Text = text; this._isSettingText = false; } // 设置输入光标 if (base.SelectionStart != start || selectionLength > 0) { this.Select(start, 0); } return true; } return false; } /// /// 粘贴文本 /// private void PasteChars() { if (!this.Enabled || this.ReadOnly) { return; } object clipboardChars = Clipboard.GetDataObject().GetData(DataFormats.UnicodeText); if (clipboardChars == null) { clipboardChars = Clipboard.GetDataObject().GetData(DataFormats.Text); if (clipboardChars == null) { return; } } if (!this.PasteChars(clipboardChars.ToString())) { WindowsAPI.MessageBeep(BeepType.MB_OK); } } /// /// 粘贴文本 /// /// private bool PasteChars(string chars) { if (string.IsNullOrEmpty(chars)) { return false; } // 原文本 string baseText = base.Text; // 选定的文本 string seletedText = base.SelectedText; // 选定文本起始位置 int selectionStart = base.SelectionStart; // 选定文本长度 int selectionLength = base.SelectionLength; // 输入后选定文本起始位置 int start = selectionStart + selectionLength; if (selectionLength > 0 && (seletedText == chars || seletedText.Replace(Constant.S_COMMA, string.Empty) == chars.Replace(Constant.S_COMMA, string.Empty))) { this.Select(start, 0); return true; } string text = this.RejectChars(ref chars, baseText, selectionStart, selectionLength); if (this.CheckInputedText(text)) { text = this.FormatText(text); TextPasteEventArgs pasteEventArgs = new TextPasteEventArgs(chars); this.OnPaste(pasteEventArgs); if (pasteEventArgs.Cancel) { return false; } // 输入后光标位置 start = this.GetKeySelectionStart(baseText, selectionStart, selectionLength, seletedText, text, chars); // 设置文本 if (baseText != text) { this._isSettingText = true; base.Text = text; this._isSettingText = false; } // 设置输入光标 if (base.SelectionStart != start || selectionLength > 0) { this.Select(start, 0); } return true; } return false; } /// /// 取得Delete删除文本后光标位置 /// /// /// /// /// /// /// private int GetDeleteSelectionStart(string baseText, int selectionStart, int selectionLength, string removedText, string text) { int start = selectionStart; if (Constant.S_NEGATIVE == removedText || // 删除负号 Constant.S_NEGATIVE == text || Constant.S_POINT == text || Constant.S_POINT == baseText) { return start; } int baseTextLength = baseText.Length; int textLength = text.Length; int baseTextPointIndex = baseText.IndexOf(Constant.C_POINT); int textPointIndex = text.IndexOf(Constant.C_POINT); #region 无选定文本 if (selectionLength == 0) { // 无效操作 if (selectionStart == baseTextLength) { return selectionStart; } int selectionEnd = selectionStart + 1; #region 删除整数部分(无小数点 或 光标在小数点前) if (baseTextPointIndex < 0 || selectionStart < baseTextPointIndex) { // 输入焦点距离字符右侧间隔 + 1 start = textLength - (baseTextLength - selectionEnd); // 光标后移一位,在【,】后面。 int startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionEnd : baseTextPointIndex - selectionEnd; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } #endregion #region 删除小数点 else if (selectionStart == baseTextPointIndex) { // 小数变为整数 int lastLength = baseTextLength - selectionEnd; if (lastLength > 0 && (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered))) { lastLength = lastLength + lastLength / 3; } // 右侧字符长度不变 start = textLength - lastLength; // 光标后移一位,在【,】后面。 if (lastLength % 4 == 0) { start++; } } #endregion #region 删除小数 else { if (baseText != text) { // 光标位置不变 start = selectionStart; } else { // 小数位全为【0】时,光标后移一位。 start++; } } #endregion } #endregion #region 选定文本 else { int selectionEnd = selectionStart + selectionLength; #region 删除整数部分(无小数点 或 选定文本在小数点前) if (baseTextPointIndex < 0 || selectionEnd <= baseTextPointIndex) { // 输入焦点(末尾)距离字符右侧间隔不变。 start = textLength - (baseTextLength - selectionEnd); // 光标后移一位,在【,】后面。 int startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionEnd : baseTextPointIndex - selectionEnd; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } #endregion #region 选定文本包括小数点 else if (selectionStart <= baseTextPointIndex && baseTextPointIndex < selectionEnd) { // 小数变为整数 int lastLength = baseTextLength - selectionEnd; if (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered)) { lastLength = lastLength + lastLength / 3; } // 补齐小数位 if (textPointIndex > -1) { // 右侧字符长度加上补齐的小数部分 start = textLength - lastLength - (textLength - textPointIndex); } // 变为整数 else { // 右侧字符长度不变 start = textLength - lastLength; } // 光标后移一位,在【,】后面。 if (lastLength % 4 == 0) { start++; } } #endregion #region 删除小数 else { if (baseText != text) { // 光标位置不变 start = selectionStart; } else { // 小数位全为【0】时,光标后移。 start = selectionStart + selectionLength; } } #endregion } #endregion return start; } /// /// 取得Back删除文本后光标位置 /// /// /// /// /// /// /// private int GetBackSelectionStart(string baseText, int selectionStart, int selectionLength, string removedText, string text) { int start = selectionStart - 1; if (Constant.S_NEGATIVE == removedText || // 删除负号 Constant.S_NEGATIVE == text || Constant.S_POINT == text || Constant.S_POINT == baseText) { return (selectionLength > 0 ? selectionStart : start); } int baseTextLength = baseText.Length; int textLength = text.Length; int baseTextPointIndex = baseText.IndexOf(Constant.C_POINT); int textPointIndex = text.IndexOf(Constant.C_POINT); #region 无选定文本 if (selectionLength == 0) { // 无效操作 if (selectionStart == 0) { return 0; } #region 删除整数部分(无小数点 或 光标在小数点前) else if (baseTextPointIndex < 0 || selectionStart <= baseTextPointIndex) { // 输入焦点距离字符右侧间隔不变。 start = textLength - (baseTextLength - selectionStart); int startIndex = 1; if (text[0] == Constant.C_NEGATIVE) { startIndex++; } // 光标在除负号外的第二位(1),并且光标后字符是【,】,光标后移一位,在【-】后面或第一位(0)。 if (selectionStart == startIndex) { startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionStart : baseTextPointIndex - selectionStart; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } } #endregion #region 删除小数点 else if (selectionStart == baseTextPointIndex + 1) { // 小数变为整数 int lastLength = baseTextLength - selectionStart; if (lastLength > 0 && (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered))) { lastLength = lastLength + lastLength / 3; } // 右侧字符长度不变 start = textLength - lastLength; } #endregion #region 删除小数 else { // 光标前移一位 start = selectionStart - 1; } #endregion } #endregion #region 选定文本 else { int selectionEnd = selectionStart + selectionLength; #region 删除整数部分(无小数点 或 选定文本在小数点前) if (baseTextPointIndex < 0 || selectionEnd <= baseTextPointIndex) { // 输入焦点(末尾)距离字符右侧间隔不变。 start = textLength - (baseTextLength - selectionEnd); int startIndex = 0; if (text[0] == Constant.C_NEGATIVE) { startIndex++; } // 光标在除负号外的第二位(1),并且光标后字符是【,】,光标后移一位,在【-】后面或第一位(0)。 if (selectionStart == startIndex) { startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionEnd : baseTextPointIndex - selectionEnd; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } else { if (removedText.EndsWith(Constant.S_COMMA)) { start--; } } } #endregion #region 选定文本包括小数点 else if (selectionStart <= baseTextPointIndex && baseTextPointIndex < selectionEnd) { // 小数变为整数 int lastLength = baseTextLength - selectionEnd; if (lastLength > 0 && (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered))) { lastLength = lastLength + lastLength / 3; } // 补齐小数位 if (textPointIndex > -1) { // 右侧字符长度加上补齐的小数部分 start = textLength - lastLength - (textLength - textPointIndex); } // 变为整数 else { // 右侧字符长度不变 start = textLength - lastLength; } } #endregion #region 删除小数 else { // 输入焦点不变。 start = selectionStart; } #endregion } #endregion return start; } /// /// 取得输入文本后光标位置 /// /// /// /// /// /// /// /// private int GetKeySelectionStart(string baseText, int selectionStart, int selectionLength, string removedText, string text, string chars) { int start = selectionStart + 1; if (Constant.S_NEGATIVE == chars || Constant.S_POINT == text) { return start; } if (REJECT_CHARS_NP == chars) { return start + 1; } int baseTextLength = baseText.Length; int textLength = text.Length; int charsLength = chars.Length; int baseTextPointIndex = baseText.IndexOf(Constant.C_POINT); int textPointIndex = text.IndexOf(Constant.C_POINT); int charsPointIndex = chars.IndexOf(Constant.C_POINT); // 无文本或全选时 if (baseTextLength == 0 || baseTextLength == selectionLength) { // 新文本没有小数部分,光标在新文本末尾 if (textPointIndex < 0) { return textLength; } // 输入字符没有小数部分,光标在小数点前 if (charsPointIndex < 0) { return textPointIndex; } // 输入字符有小数部分,光标在补齐位数前 if (charsPointIndex > -1) { return textPointIndex + charsLength - charsPointIndex; } } #region 无选定文本(插入) if (selectionLength == 0) { #region 输入字符不带小数点 if (charsPointIndex < 0) { #region 整数部分(无小数点 或 光标在小数点前) if (baseTextPointIndex < 0 || selectionStart <= baseTextPointIndex) { // 输入前无小数,输入后有小数 if (baseTextPointIndex < 0 && textPointIndex >= 0) { start = textPointIndex; } else { // 输入焦点距离字符右侧间隔不变。 start = textLength - (baseTextLength - selectionStart); if (baseTextPointIndex == baseTextLength - 1 && textPointIndex != textLength - 1) { start = start - textLength + textPointIndex + 1; } else { // 光标后移一位,在【,】后面。 int startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionStart : baseTextPointIndex - selectionStart; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } } } #endregion #region 小数部分 else { // 光标后移输入字符串长度 start = selectionStart + charsLength; } #endregion } #endregion #region 输入字符带小数点 else { // 光标在输入字符串末尾 start = textPointIndex + charsLength - charsPointIndex; } #endregion } #endregion #region 选定文本(替换) else { int selectionEnd = selectionStart + selectionLength; #region 输入字符不带小数点 if (charsPointIndex < 0) { #region 整数部分(无小数点 或 光标在小数点前) if (baseTextPointIndex < 0 || selectionEnd <= baseTextPointIndex) { // 输入焦点距离字符右侧间隔不变。 start = textLength - (baseTextLength - selectionEnd); if (baseTextPointIndex == baseTextLength - 1 && textPointIndex != textLength - 1) { start = start - textLength + textPointIndex + 1; } else { // 光标后移一位,在【,】后面。 int startIndex = baseTextPointIndex < 0 ? baseTextLength - selectionStart : baseTextPointIndex - selectionStart; if (startIndex > 0 && startIndex % 4 == 0) { start++; } } } #endregion #region 小数部分 else if (selectionStart > baseTextPointIndex) { // 光标后移输入字符串长度。 start = selectionStart + charsLength; } #endregion #region 选定小数点 else { // 小数变为整数 int lastLength = baseTextLength - selectionEnd; if (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered)) { lastLength = lastLength + lastLength / 3; } // 补齐小数位 if (textPointIndex > -1) { // 右侧字符长度加上补齐的小数部分 start = textLength - lastLength - (textLength - textPointIndex); } // 变为整数 else { // 右侧字符长度不变 start = textLength - lastLength; } // 右侧字符长度不变 //start = textLength - lastLength; // 光标后移一位,在【,】后面。 if (lastLength % 4 == 0) { start++; } } #endregion } #endregion #region 输入字符带小数点 else { // 光标在输入字符串末尾 start = textPointIndex + charsLength - charsPointIndex; } #endregion } #endregion return start; } /// /// 将数值转换为字符串表示形式 /// /// /// /// /// /// private string ToText(decimal value, bool hasNegatve, int hasPoint, int pointLength) { string dec = null; if (this._number.Y > 0) { if (this._showDecimalPlaces == ShowDigitalKind.Always || (this._showDecimalPlaces == ShowDigitalKind.NoFocus && !this._entered)) { dec = Constant.S_POINT.PadRight(this._number.Y + 1, Constant.C_0); } else { if (this._entered) { if (this._limitInputKind.HasFlag(LimitInputKind.Decimal)) { pointLength = Math.Min(pointLength, this._number.Y); } dec = Constant.S_POINT.PadRight(pointLength + 1, Constant.C_0); } else { dec = Constant.S_POINT.PadRight(this._number.Y + 1, Constant.C_WELL); } } } string comma = null; if (this._thousandsSeparator == ShowDigitalKind.Always || (this._thousandsSeparator == ShowDigitalKind.NoFocus && !this._entered)) { comma = COMMA_HAS + ((this._entered && hasPoint == -1) ? Constant.S_WELL : Constant.S_0) + dec; } else { comma = COMMA_NOT + ((this._entered && hasPoint == -1) ? Constant.S_WELL : Constant.S_0) + dec; } string text = value.ToString(comma, CultureInfo.CurrentCulture); if (hasPoint == -2 && text.IndexOf(Constant.C_POINT) < 0) { text += Constant.S_POINT; } return (value < 0 || !hasNegatve) ? text : Constant.S_NEGATIVE + text; } /// /// 验证输入后的新文本(OnKeyDown delete or back) /// /// 输入后的新文本 /// 是否通过验证,true 通过,false 不通过 private bool CheckInputedText(string text) { if (text.Length == 0) { return true; } if (text.Length == 1) { char t1 = text[0]; // 是否可以输入小数点 if (Constant.C_POINT == t1) { return this._number.Y > 0; } // 是否可以输入负号 if (Constant.C_NEGATIVE == t1) { return this._minNumberValue < 0; } } // 【-.】 if (text == TextBoxNumerical.REJECT_CHARS_NP) { return true; } decimal d = 0; if (!decimal.TryParse(text, out d)) { // 不能转为数值 return false; } int pointIndex = text.IndexOf(Constant.S_POINT); // 有小数点 if (pointIndex > -1) { // 不能输入小数 if (this._number.Y == 0) { return false; } // todo ? text = d.ToString(); pointIndex = text.IndexOf(Constant.S_POINT); // 去掉小数部分多余的【0】 if (pointIndex > -1) { text = text.TrimEnd(Constant.C_0); } // 验证整数部分长度 if (this._number.X > 0 && this._limitInputKind.HasFlag(LimitInputKind.Integer)) { int textStart = (text[0] == Constant.C_NEGATIVE ? 1 : 0); if (pointIndex - textStart > this._number.X) { return false; } } // 验证小数部分长度 if (this._number.Y > 0 && this._limitInputKind.HasFlag(LimitInputKind.Decimal)) { if (text.Length - pointIndex - 1 > this._number.Y) { return false; } } } else { // 无小数点时,验证整数部分长度 if (this._number.X > 0 && this._limitInputKind.HasFlag(LimitInputKind.Integer)) { int textStart = (text[0] == Constant.C_NEGATIVE ? 1 : 0); if (text.Length - textStart > this._number.X) { return false; } } } // 验证数据范围 if (this._limitInputKind.HasFlag(LimitInputKind.Range)) { if (d > this._maxNumberValue) { return false; } if (d < this._minNumberValue) { return false; } //if (!this._allowZero && d == 0) //{ // return false; //} if (!this._allowNegative && d < 0) { return false; } } return true; } /// /// 验证数值 /// /// private decimal CheckDataValue(decimal value) { if (value > this._maxNumberValue) { value = this._maxNumberValue; } if (value < this._minNumberValue) { value = this._minNumberValue; } return value; } /// /// 验证输入的字符(paste or check all text) /// /// 输入的字符 /// 现有文本 /// 选定文本的起始点 /// 选定的字符数 /// 是否通过验证的文本 private string RejectChars(ref string chars, string text, int selectionStart = 0, int selectionLength = 0) { // 去掉选定的字符 if (selectionLength > 0) { text = text.Remove(selectionStart, selectionLength); } if (string.IsNullOrEmpty(chars)) { chars = string.Empty; } else { //chars = chars.Replace(REJECT_CHARS_ALL, string.Empty); chars = Regex.Replace(chars, REJECT_CHARS_ALL, string.Empty); } // 过滤输入字符 if (chars.Length > 0) { // 过滤负号 bool noNegatve = selectionStart > 0 || !this._allowNegative; // 过滤小数点 bool noPoint = this._number.Y == 0; if (text.Length > 0) { // 文本中已经有负号 noNegatve = noNegatve || text[0] == Constant.C_NEGATIVE; // 文本中已经有小数点 noPoint = noPoint || text.Contains(Constant.S_POINT); } //string rejected = TextBoxDigital.REJECT_CHARS_ALL; // 输入字符中是否有负号 bool hasNegatve = (chars[0] == Constant.C_NEGATIVE); // 过滤掉无用字符 chars = chars.Replace(Constant.S_NEGATIVE, string.Empty); if (noPoint) { //chars = chars.Replace(Constant.S_POINT, string.Empty); int indexPoint = chars.IndexOf(Constant.S_POINT); if (indexPoint > -1) { chars = chars.Remove(indexPoint); } } // 允许为负数并且输入负号 if (!noNegatve && hasNegatve) { chars = chars + Constant.C_NEGATIVE; } // 允许为小数并且输入小数点 if (!noPoint) { string[] p = chars.Split(Constant.C_POINT); if (p.Length > 2) { chars = string.Join(Constant.S_POINT, p, 0, 2) + string.Join(string.Empty, p, 2, p.Length); } } } if (text.Length > 0 && chars.Length > 0) { text = text.Insert(selectionStart, chars); } else if (text.Length == 0) { text = chars; } return text.Replace(Constant.S_COMMA, string.Empty); } /// /// 格式化显示文本 /// /// 文本 /// 格式化后的文本 private string FormatText(string text) { if (string.IsNullOrEmpty(text)) { this._dataValue = null; return string.Empty; } if (Constant.S_NEGATIVE == text || Constant.S_POINT == text || TextBoxNumerical.REJECT_CHARS_NP == text) { this._dataValue = 0; if (this._entered) { return text; } else { if (this._showDecimalPlaces == ShowDigitalKind.Always || this._showDecimalPlaces == ShowDigitalKind.NoFocus) { return Constant.S_0 + Constant.S_POINT.PadRight(Number.Y + 1, Constant.C_0); } else { return Constant.S_0; } } } decimal d = 0; if (!decimal.TryParse(text, out d)) { this._dataValue = null; return text; } // 负号 bool hasNegative = (text[0] == Constant.C_NEGATIVE); // 小数点(0:无特殊处理;-1:开始位置;-2:结束位置) int pointIndex = text.IndexOf(Constant.C_POINT); int hasPoint = 0; int pointLength = 0; if (pointIndex > -1) { pointLength = text.Length - pointIndex - 1; if (pointIndex == 0 || (hasNegative && pointIndex == 1)) { hasPoint = -1; } else if (pointLength == 0) { hasPoint = -2; } } this._dataValue = this.CheckDataValue(d); return this.ToText(this._dataValue.Value, hasNegative, hasPoint, pointLength); } /// /// 确定最大最小值 /// /// private bool SetDNumberValue() { if (this._number.X > 0) { this._maxDNumberValue = DNumber.ToDecimal(this._number); this._minDNumberValue = (this._allowNegative ? 0 - this._maxDNumberValue : 0); } else { this._maxDNumberValue = decimal.MaxValue; this._minDNumberValue = (this._allowNegative ? decimal.MinValue : 0); } return this.SetMaxOrMinValue(); } /// /// 确定最大最小值 /// /// private bool SetMaxOrMinValue() { bool isChanged = false; decimal value = Math.Min(this._maxValue, this._maxDNumberValue); if (this._maxNumberValue != value) { isChanged = true; this._maxNumberValue = value; } value = Math.Max(this._minValue, this._minDNumberValue); if (this._minNumberValue != value) { isChanged = true; this._minNumberValue = value; } return isChanged; } /// /// 使父控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向父控件发送绘制消息。 /// private void InvalidateBorder() { Color? borderColor = BorderColorPaint.GetBorderColor(this as IDataVerifiable, this._entered, this._mouseOver); if (borderColor != this._borderColor) { this._borderColor = borderColor; if (this.Parent == null) { this.Invalidate(); } else { this.Parent.Invalidate(this.Bounds, true); } } } #endregion #region IDataVerifiable 成员 #region 成员变量 /// /// 显示边框颜色 /// private bool _showBorderColor = true; /// /// 控件的项目名 /// private string _itemName = null; /// /// 控件是否是必须输入项目 /// private bool _mustInput = false; /// /// 控件在验证输入错误时,如何提示 /// private InputErrorAlert _errorAlert = InputErrorAlert.Validated; /// /// 是否显示必须输入项目的提示 /// private bool _showMustInputAlert = true; /// /// 验证不通过时,焦点能否离开 /// private bool _canLostFocusOnError = true; /// /// 验证是否有错误 /// private bool _hasError = false; /// /// 是否自定义错误 /// private bool _hasCustomerError = false; /// /// 错误编码 /// private ControlErrorCode _errorCode = ControlErrorCode.DKC_0000; /// /// 错误消息 /// private string _errorMessage = null; /// /// 自定义错误消息 /// private string _customerErrorMessage = null; #endregion #region 属性 /// /// 获取或设置控件是否显示边框颜色。 /// [Description("获取或设置控件是否显示边框颜色。"), Category("IDataVerifiable")] [DefaultValue(true)] public bool ShowBorderColor { get { return this._showBorderColor; } set { if (this._showBorderColor != value) { this._showBorderColor = value; this.InvalidateBorder(); } } } /// /// 获取或设置控件的项目名 /// [Description("获取或设置控件的项目名。"), Category("IDataVerifiable")] [DefaultValue(null)] public string CDItemName { get { return this._itemName; } set { this._itemName = value; } } /// /// 获取或设置控件是否必须选中项目。 /// [Description("获取或设置控件是否必须选中项目。"), Category("IDataVerifiable")] [DefaultValue(false)] public bool MustInput { get { return this._mustInput; } set { if (this._mustInput != value) { if (!this._mustInput && value) { this._mustInput = value; this.SetTextValue(); } else { this._mustInput = value; } this.ValidateData(); if (value && this._showMustInputAlert) { this.InvalidateBorder(); } } } } /// /// 获取或设置控件是否必须选中项目。 /// [Description("获取或设置控件在验证输入错误时,如何提示。"), Category("IDataVerifiable")] [DefaultValue(typeof(InputErrorAlert), "Validated")] public InputErrorAlert InputErrorAlert { get { return this._errorAlert; } set { if (this._errorAlert != value) { this._errorAlert = value; this.InvalidateBorder(); } } } /// /// 获取或设置控件是否显示必须输入项目提示 /// [Description("获取或设置控件是否显示必须输入项目提示。"), Category("IDataVerifiable")] [DefaultValue(true)] public bool ShowMustInputAlert { get { return this._showMustInputAlert; } set { if (this._showMustInputAlert != value) { this._showMustInputAlert = value; this.InvalidateBorder(); } } } /// /// 获取或设置当验证不通过时,控件是否可以失去焦点 /// [Description("获取或设置当验证不通过时,控件是否可以失去焦点。"), Category("IDataVerifiable")] [DefaultValue(true)] public bool CanLostFocusOnError { get { return this._canLostFocusOnError; } set { this._canLostFocusOnError = value; } } /// /// 获取控件校验时是否有错误 /// [Description("获取控件校验时是否有错误。"), Category("IDataVerifiable")] [DefaultValue(false)] public bool HasError { get { return this._hasCustomerError || this._hasError; } } /// /// 获取控件校验时的错误编码 /// [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")] [DefaultValue(typeof(ControlErrorCode), "DKC_0000")] public ControlErrorCode ErrorCode { get { return this._hasCustomerError ? ControlErrorCode.DKC_C001 : this._errorCode; } } /// /// 获取控件校验时的错误消息 /// [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")] [DefaultValue(null)] public string ErrorMessage { get { return this._hasCustomerError ? this._customerErrorMessage : this._errorMessage; } } #endregion #region 公有方法 /// /// 设置自定义错误 /// /// 输入是否有错误 /// 错误消息 public virtual void SetCustomerError(bool hasError, string errorMessage) { if (this._hasCustomerError != hasError || this._customerErrorMessage != errorMessage) { this._hasCustomerError = hasError; this._customerErrorMessage = errorMessage; this.OnHasErrorChanged(EventArgs.Empty); this.InvalidateBorder(); } } /// /// 清除自定义错误 /// public virtual void ClearCustomerError() { this.SetCustomerError(false, null); } /// /// 验证输入内容 /// /// 验证结果 public virtual bool ValidateData() { string text = base.Text; if (this._mustInput && text.Length == 0) { this.SetError(true, ControlErrorCode.DKC_0001, this._itemName); return false; } this.ClearError(); return true; } /// /// 清除输入项 /// public virtual void ClearValue() { this.Clear(); } #endregion #region 保护方法 /// /// 设置验证不通过错误 /// /// 是否有错误 /// 错误编码 /// 设置格式的对象 protected void SetError(bool hasError, ControlErrorCode code, params object[] args) { if (this._hasError != hasError || this._errorCode != code) { this._hasError = hasError; this._errorCode = code; if (args != null && args.Length > 0) { this._errorMessage = string.Format(code.GetDescription(), args); } else { this._errorMessage = code.GetDescription(); } this.OnHasErrorChanged(EventArgs.Empty); this.InvalidateBorder(); } } /// /// 清除验证不通过错误 /// protected void ClearError() { this.SetError(false, ControlErrorCode.DKC_0000); } #endregion #endregion #region IAsyncControl 成员 #region 成员变量 /// /// 异步处理开始时,控件状态 /// private bool _asyncBeginStatus = false; private bool _asyncBeginFocused = false; #endregion #region 公有方法 /// /// 开始异步处理 /// /// 是否处理焦点 public virtual void BeginAsync(ref bool doFocus) { this._asyncBeginFocused = false; if (doFocus && this.Focused) { this._asyncBeginFocused = true; doFocus = false; } this._asyncBeginStatus = this.ReadOnly; this.ReadOnly = true; } /// /// 结束异步处理 /// public virtual void EndAsync() { this.ReadOnly = this._asyncBeginStatus; if (this._asyncBeginFocused) { this.Focus(); } } #endregion #endregion } }