using System; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Forms; using Dongke.WinForm.Utilities; namespace Dongke.WinForm.Controls { /// /// 日期控件,该控件用来让用户选择日期和时间并以指定的格式显示此日期和时间。 /// public abstract class DateTimePickerBase : DateTimePicker, IDKControl, IDataVerifiable, IAsyncControl, IChildNativeWindow { #region 常量 /// /// 日期时间格式过滤字符 /// private const string DATETIME_FORMAT_S = "[^yMdHhmsfFt]"; #endregion #region 获取UpDown控件 [DllImport("user32.dll", ExactSpelling = true)] private static extern bool EnumChildWindows(HandleRef hwndParent, DateTimePickerBase.EnumChildrenCallback lpEnumFunc, HandleRef lParam); private delegate bool EnumChildrenCallback(IntPtr hwnd, IntPtr lParam); private sealed class EnumChildren { public IntPtr hwndFound = IntPtr.Zero; public bool enumChildren(IntPtr hwnd, IntPtr lparam) { this.hwndFound = hwnd; return true; } } #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 ChildNativeWindow _updown = null; /// /// 焦点是否进入控件 /// private bool _entered = false; /// /// 鼠标是否进入控件 /// private bool _mouseOver = false; /// /// 边框颜色 /// private Color? _borderColor = null; /// /// 自定义日期/时间格式字符串 /// private string _customFormat = Constant.DATETIME_FORMAT_YYYYMMDDHHMMSS; /// /// 控件中显示的日期和时间格式 /// private DateTimePickerFormat _format = DateTimePickerFormat.Custom; /// /// 指示是否设定了日期时间值 /// private bool _nullValue = false; /// /// 指示控件是否允许输入null /// private bool _allowNull = true; /// /// 不触发ValueChanged /// private bool _isSetValue = false; /// /// 日期文本(无标点)格式化 /// private string _dateTextFormat = null; /// /// 日历选择显示 /// private bool _isDropDown = false; #endregion #region 构造函数 /// /// 日期控件,该控件用来让用户选择日期和时间并以指定的格式显示此日期和时间。 /// public DateTimePickerBase() { base.ImeMode = ImeMode.Off; this.Value = null; this._dateTextFormat = Regex.Replace(this._customFormat, DATETIME_FORMAT_S, string.Empty); 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(); } } } /// /// 获取日期的开始时间(该日期的00:00:00) /// [Browsable(true), Description("获取日期的开始时间(该日期的00:00:00)"), Category("CustomerEx")] public virtual DateTime? BeginTime { get { if (this._nullValue) { return null; } return this.Value.Value.Date; } } /// /// 获取日期的结束时间(该日期的23:59:59) /// [Browsable(true), Description("获取日期的结束时间(该日期的23:59:59)"), Category("CustomerEx")] public virtual DateTime? EndTime { get { if (this._nullValue) { return null; } DateTime dt = this.Value.Value; return new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59); } } /// /// 获取或设置与此控件关联的日期文本(无格式)。 /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public virtual string DateText { get { if (this._nullValue) { return string.Empty; } // 日期时间改变时,控件闪烁。 //if (this.Focused) //{ // // 输入不完整时,自动补齐日期。 // SendKeys.SendWait("{RIGHT}"); // SendKeys.SendWait("{LEFT}"); //} return this.Value.Value.ToString(this._dateTextFormat); } set { if (value == null || value.Length == 0) { this.Value = null; return; } DateTime dt; if (DateTime.TryParseExact(value, this._dateTextFormat, null, System.Globalization.DateTimeStyles.None, out dt)) { this.Value = dt; } } } #endregion #region 重写属性 /// /// 获取或设置自定义日期/时间格式字符串。 /// [DefaultValue(Constant.DATETIME_FORMAT_YYYYMMDDHHMMSS)] public new virtual string CustomFormat { get { return this._customFormat; } set { this._customFormat = value; this._dateTextFormat = Regex.Replace(this._customFormat, DATETIME_FORMAT_S, string.Empty); if (!this._nullValue) { base.CustomFormat = value; } } } /// /// 获取或设置控件中显示的日期和时间格式。 /// [DefaultValue(typeof(DateTimePickerFormat), "Custom")] public new virtual DateTimePickerFormat Format { get { return this._format; } set { this._format = value; if (!this._nullValue) { base.Format = value; } } } /// /// 获取或设置与此控件关联的格式化文本。 /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public override string Text { get { if (this._nullValue) { return string.Empty; } // 日期时间改变时,控件闪烁。 //// 输入不完整时,自动补齐日期。 //if (this.Focused && !this._isDropDown) //{ // SendKeys.SendWait("{RIGHT}"); // SendKeys.SendWait("{LEFT}"); //} return base.Text; } set { if (value == null || value.Length == 0) { this.Value = null; return; } if (this._nullValue) { this.SetDateValueNotNull(); } base.Text = value; } } /// /// 获取或设置分配给控件的日期/时间值。 /// //[Browsable(false)] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] //[EditorBrowsable(EditorBrowsableState.Never)] [Bindable(true)] [DefaultValue(typeof(DateTime?), "")] [RefreshProperties(RefreshProperties.All)] [Description("获取或设置分配给控件的日期/时间值。"), Category("CustomerEx")] public new virtual DateTime? Value { get { if (this._allowNull && this._nullValue) { return null; } // 日期时间改变时,控件闪烁。 //// 输入不完整时,自动补齐日期。 //if (this.Focused && !this._isDropDown) //{ // SendKeys.SendWait("{RIGHT}"); // SendKeys.SendWait("{LEFT}"); //} return base.Value; } set { if (value.HasValue) { this.SetDateValueNotNull(value.Value); } else { if (!this._allowNull) { return; } if (!this._nullValue) { this.SetDateValueNull(); } } } } /// /// 获取或设置一个值,该值指示控件是否允许输入null值。 /// [DefaultValue(true)] [RefreshProperties(RefreshProperties.All)] [Description("获取或设置一个值,该值指示控件是否允许输入null值。"), Category("CustomerEx")] public virtual bool AllowNull { get { return this._allowNull; } set { this._allowNull = value; if (!this._allowNull && this._nullValue) { this.SetDateValueNotNull(); } } } /// /// 获取或设置控件的输入法编辑器 (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; } } #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) { base.OnTextChanged(EventArgs.Empty); } /// /// /// /// protected override void OnValueChanged(EventArgs e) { if (this._nullValue && !this._isSetValue) { return; } // 不显示天数时,如果是31日,没有31日的月份会报错。 if (!this._nullValue && this.Format == DateTimePickerFormat.Custom && this.CustomFormat != null && !this.CustomFormat.Contains("d") && this.Value.Value.Day > 28) { this.Value = this.Value.Value.AddDays(1 - this.Value.Value.Day); } base.OnValueChanged(e); // TODO 实时验证? if (true) { this.ValidateData(); } } #endregion #region 行为事件 /// /// 当显示下拉日历时发生。 /// /// protected override void OnDropDown(EventArgs e) { base.OnDropDown(e); this._isDropDown = true; } /// /// 当下拉日历被关闭并消失时发生 /// /// protected override void OnCloseUp(EventArgs e) { if (!this._allowNull) { base.OnCloseUp(e); return; } if (this.ShowCheckBox && !this.Checked) { base.OnCloseUp(e); return; } if (Control.MouseButtons == MouseButtons.None) { if (this._nullValue) { //this.Value = base.Value; this.SetDateValueNotNull(base.Value); } } base.OnCloseUp(e); this._isDropDown = false; } #endregion #region 键盘事件 /// /// 当有按键动作时发生 /// /// protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) { if (!this._allowNull) { base.OnPreviewKeyDown(e); return; } if (this.ShowCheckBox && !this.Checked) { base.OnPreviewKeyDown(e); return; } // 删除时间 if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete) { this.Value = null; base.OnPreviewKeyDown(e); return; } if ((e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9) || (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.PageUp && e.KeyCode <= Keys.Down)) { //PageUp = 33, //Next = 34, //PageDown = 34, //End = 35, //Home = 36, //Left = 37, //Up = 38,。 //Right = 39, //Down = 40, if (this._nullValue) { this.SetDateValueNotNull(); if (e.KeyCode != Keys.Right) { SendKeys.SendWait("{RIGHT}"); } } } base.OnPreviewKeyDown(e); } /// /// 键盘输入 /// /// protected override void OnKeyPress(KeyPressEventArgs e) { base.OnKeyPress(e); } /// /// 键盘点击 /// /// protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); } #endregion #region 焦点事件 /// /// 输入焦点进入控件 /// /// protected override void OnEnter(EventArgs e) { this.Entered = true; base.OnEnter(e); } /// /// 获得焦点 /// /// protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); } /// /// 失去焦点 /// /// protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); } /// /// 输入焦点离开控件 /// /// protected override void OnLeave(EventArgs e) { base.OnLeave(e); } /// /// 控件正在验证 /// /// protected override void OnValidating(CancelEventArgs e) { base.OnValidating(e); if (this.HasError && !this._canLostFocusOnError) { e.Cancel = true; } } /// /// 控件完成验证 /// /// protected override void OnValidated(EventArgs e) { this.Entered = 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 重写方法 /// /// 返回表示当前 System.Windows.Forms.DateTimePicker 控件的字符串。 /// /// public override string ToString() { if (this._nullValue) { return string.Empty; } return base.ToString(); } /* public struct NMHDR { public IntPtr hwndFrom; public IntPtr idFrom; public int code; } [StructLayout(LayoutKind.Sequential)] public class SYSTEMTIME { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; public override string ToString() { return string.Concat(new string[] { "[SYSTEMTIME: ", this.wDay.ToString(CultureInfo.InvariantCulture), "/", this.wMonth.ToString(CultureInfo.InvariantCulture), "/", this.wYear.ToString(CultureInfo.InvariantCulture), " ", this.wHour.ToString(CultureInfo.InvariantCulture), ":", this.wMinute.ToString(CultureInfo.InvariantCulture), ":", this.wSecond.ToString(CultureInfo.InvariantCulture), "]" }); } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class NMDATETIMECHANGE { public NMHDR nmhdr; public int dwFlags; public SYSTEMTIME st; } internal static SYSTEMTIME DateTimeToSysTime(DateTime time) { return new SYSTEMTIME { wYear = (short)time.Year, wMonth = (short)time.Month, wDayOfWeek = (short)time.DayOfWeek, wDay = (short)time.Day, wHour = (short)time.Hour, wMinute = (short)time.Minute, wSecond = (short)time.Second, wMilliseconds = 0 }; } [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, SYSTEMTIME lParam); */ /// /// 处理 Windows 消息 /// /// 要处理的 Windows System.Windows.Forms.Message protected override void WndProc(ref Message m) { /* if (m.Msg == 0x204E) { if (m.HWnd == base.Handle) { NMDATETIMECHANGE nMDATETIMECHANGE = (NMDATETIMECHANGE)m.GetLParam(typeof(NMDATETIMECHANGE)); if (nMDATETIMECHANGE.nmhdr.code == -759) { if (nMDATETIMECHANGE.dwFlags != 1) { if (nMDATETIMECHANGE.st.wYear == 0) { return; } } } } } */ if (this.ShowUpDown) { if (this._updown == null) { DateTimePickerBase.EnumChildren enumChildren = new DateTimePickerBase.EnumChildren(); DateTimePickerBase.EnumChildrenCallback lpEnumFunc = new DateTimePickerBase.EnumChildrenCallback(enumChildren.enumChildren); DateTimePickerBase.EnumChildWindows(new HandleRef(this, base.Handle), lpEnumFunc, WindowsAPI.NullHandleRef); if (enumChildren.hwndFound != IntPtr.Zero) { this._updown = new ChildNativeWindow(this, "UpDown"); this._updown.AssignHandle(enumChildren.hwndFound); } } } else { if (this._updown != null) { this._updown.ReleaseHandle(); this._updown = null; } } base.WndProc(ref m); // 释放句柄 if (m.Msg == (int)WindowsMessage.WM_NCDESTROY) { if (this._updown != null) { this._updown.ReleaseHandle(); this._updown = null; } return; } 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 保护方法 /// /// 处理DateTimePickerBase内部控件的消息 /// /// UpDown /// 消息 /// 消息是否已经处理过 public virtual bool ChildWndProc(ChildNativeWindow child, ref Message m) { switch (m.Msg) { case (int)WindowsMessage.WM_LBUTTONDOWN: if (this._nullValue) { this.SetDateValueNotNull(); if (!this.Focused) { this.Focus(); } SendKeys.SendWait("{RIGHT}"); return true; } break; } return false; } #endregion #region 私有方法 /// /// 使父控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向父控件发送绘制消息。 /// 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); } } } /// /// 设置日期 /// /// 日期 private void SetDateValueNotNull(DateTime value) { if (this._nullValue) { base.Format = this._format; base.CustomFormat = this._customFormat; this._nullValue = false; if (base.Value != value) { this.SetBaseValue(value); } else { this.OnValueChanged(EventArgs.Empty); this.OnValidated(EventArgs.Empty); } } else { if (base.Value != value) { this.SetBaseValue(value); } } } /// /// 设置空日期 /// private void SetDateValueNull() { base.Format = DateTimePickerFormat.Custom; base.CustomFormat = Constant.S_SPACE; this._nullValue = true; // TODO null 时的默认时间 this.SetBaseValue(DateTime.Now); } /// /// 设置日期(当前时间) /// private void SetDateValueNotNull() { base.Format = this._format; base.CustomFormat = this._customFormat; this._nullValue = false; // TODO null 时的默认时间 this.SetBaseValue(DateTime.Now); } /// /// 设置日期 /// /// 日期 private void SetBaseValue(DateTime vaue) { this._isSetValue = true; base.Value = vaue; this._isSetValue = false; if (!this.Focused) { this.OnValidated(EventArgs.Empty); } } #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) { this._mustInput = value; this.ValidateData(); if (this._mustInput && 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() { if (this._mustInput && this._nullValue) { this.SetError(true, ControlErrorCode.DKC_0001, this._itemName); return true; } this.ClearError(); return false; } /// /// 清除输入项 /// public virtual void ClearValue() { //this.Value = null; if (this._allowNull) { this.Value = null; } else { this.Value = DateTime.Now; } } #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 成员 /// /// 异步处理开始时,控件状态 /// private bool _asyncBeginStatus = false; private bool _asyncBeginFocused = false; /// /// 异步处理开始 /// /// 是否处理焦点 public virtual void BeginAsync(ref bool doFocus) { this._asyncBeginFocused = false; if (doFocus && this.Focused) { this._asyncBeginFocused = true; doFocus = false; } this._asyncBeginStatus = this.Enabled; this.Enabled = false; } /// /// 异步处理结束 /// public virtual void EndAsync() { this.Enabled = this._asyncBeginStatus; if (this._asyncBeginFocused) { this.Focus(); } } #endregion } }