using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; using Dongke.WinForm.Utilities; namespace Dongke.WinForm.Controls { /// /// 窗体基类 /// public partial class FormBase : Form, IDKForm { #region 事件声明 #region AsyncBegin /// /// 当异步处理开始时发生。 /// private static readonly object EventAsyncBegin = new object(); /// /// 当异步处理开始时发生。 /// [Description("当异步处理开始时发生。"), Category("CustomerEx")] public event CancelEventHandler AsyncBegin { add { base.Events.AddHandler(EventAsyncBegin, value); } remove { base.Events.RemoveHandler(EventAsyncBegin, value); } } /// /// 引发 异步处理开始 事件 /// /// 包含事件数据的 EventArgs protected virtual void OnAsyncBegin(CancelEventArgs e) { CancelEventHandler eventHandler = (CancelEventHandler)base.Events[EventAsyncBegin]; if (eventHandler != null) { eventHandler(this, e); } } #endregion #region AsyncEnd /// /// 当异步处理结束时发生。 /// private static readonly object EventAsyncEnd = new object(); /// /// 当异步处理结束时发生。 /// [Description("当异步处理开始时发生。"), Category("CustomerEx")] public event AsyncEndEventHandler AsyncEnd { add { base.Events.AddHandler(EventAsyncEnd, value); } remove { base.Events.RemoveHandler(EventAsyncEnd, value); } } /// /// 引发 异步处理结束 事件 /// /// 包含事件数据的 EventArgs protected virtual void OnAsyncEnd(AsyncEndEventArgs e) { AsyncEndEventHandler eventHandler = (AsyncEndEventHandler)base.Events[EventAsyncEnd]; if (eventHandler != null) { eventHandler(this, e); } } #endregion #endregion #region 成员变量 /// /// 异步等处理时,能否关闭窗体 /// private bool _canClose = true; private bool _isClosing = false; private bool _isSaving = false; /// /// 是否取消异步处理。 /// private bool _cancelAsync = false; /// /// 正在异步处理。 /// private bool _doAsync = false; /// /// 窗体中数据是否被修改过 /// private bool _isDirty = false; private bool _showStatusStrip = true; /// /// 窗体类型 /// private FormType _formType = FormType.Select; private FormWindowState _formWindowState = FormWindowState.Normal; private string _formCode = null; private bool _doFocus = true; private int _loadCount = 0; #endregion #region 构造函数 /// /// 窗体基类 /// protected FormBase() : this(null) { } /// /// 窗体基类 /// protected FormBase(string formCode) { InitializeComponent(); this.KeyPreview = true; this._formCode = formCode; if (this._showStatusStrip) { this.Controls.Add(this.ssrAsyncStatusStrip); } else { this.Controls.Remove(this.ssrAsyncStatusStrip); } this.ssrAsyncStatusStrip.Visible = this._showStatusStrip; } #endregion #region 属性 /// /// 获取一个值,该值指示窗体的编码(多实例窗体编码不同)。 /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public string FormCode { get { return this._formCode; } set { this._formCode = value; } } /// /// 获取一个值,该值指示是否正在异步处理。 /// [DefaultValue(false)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] [Description("获取一个值,该值指示是否正在异步处理。"), Category("CustomerEx")] public bool AsyncDoing { get { return this._doAsync; } } /// /// 获取一个值,该值指示异步处理是否被取消。 /// [DefaultValue(false)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] [Description("获取一个值,该值指示异步处理是否被取消。"), Category("CustomerEx")] public bool AsyncCanecled { get { return this._cancelAsync; } } /// /// 获取或设置一个值,该值指示窗体中数据是否被修改过。 /// [DefaultValue(false)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] [Description("获取或设置一个值,该值指示窗体中数据是否被修改过。"), Category("CustomerEx")] public bool Dirty { get { return this._isDirty || this.CheckDirty(); } set { this._isDirty = value; } } /// /// 窗体类型 /// [Description("获取或设置一个值,该值指示窗体中数据是否被修改过。"), Category("CustomerEx")] [DefaultValue(typeof(FormType), "Select")] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Advanced)] public FormType FormType { get { return this._formType; } set { this._formType = value; } } /// /// 获取或设置一个值,该值指示是否显示状态条。 /// [Description("获取或设置一个值,该值指示是否显示状态条。"), Category("CustomerEx")] [DefaultValue(true)] public virtual bool ShowStatusStrip { get { return this._showStatusStrip; } set { if (this._showStatusStrip != value) { this._showStatusStrip = value; if (this._showStatusStrip) { this.Controls.Add(this.ssrAsyncStatusStrip); } else { this.Controls.Remove(this.ssrAsyncStatusStrip); } this.ssrAsyncStatusStrip.Visible = value; } } } #endregion #region 重写属性 /// /// 获取或设置窗体的边框样式。 /// //[Browsable(false)] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] //[EditorBrowsable(EditorBrowsableState.Advanced)] public virtual new FormBorderStyle FormBorderStyle { get { return base.FormBorderStyle; } set { base.FormBorderStyle = value; this.SetStatusSizingGrip(); } } /// /// 获取或设置运行时窗体的起始位置 /// [Localizable(true)] [DefaultValue(typeof(FormStartPosition), "CenterScreen")] public virtual new FormStartPosition StartPosition { get { return base.StartPosition; } set { base.StartPosition = value; } } #endregion #region 重写事件 private bool _closeOnEsc = true; public bool CloseOnEsc { get { return this._closeOnEsc; } set { this._closeOnEsc = value; } } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (this.CancelButton == null && e.KeyData == Keys.Escape && this._closeOnEsc) { this.Close(); } } /// /// 窗体大小改变 /// /// protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); if (this.WindowState != FormWindowState.Minimized) { this._formWindowState = this.WindowState; } this.SetStatusSizingGrip(); } /// /// 窗体关闭时 /// /// protected override void OnClosed(EventArgs e) { base.OnClosed(e); FormFactory.RemoveForm(this); try { // datagridview控件设置保存(TODO) System.Collections.Generic.List items = this.GetControls(this, typeof(Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView)); foreach (Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView grd in items) { if (grd.IsSaveDataGridViewSetting) { Dongke.IBOSS.PRD.Basics.Library.GridSettingManager.SaveGridSetting(grd, this.Name + grd.Name); } } } catch /*(Exception ex)*/ { //Dongke.IBOSS.MBC.Basics.Library.OutputLog.TraceLog( Dongke.IBOSS.MBC.Basics.Library.LogPriority.Error, // "Dongke.WinForm.Controls.FormBase", "SaveGridSetting", ex.Message, logFilePath); } } /// /// 正在关闭窗体时 /// /// protected override void OnClosing(CancelEventArgs e) { // 画面暂不能关闭 if(!this._canClose) { e.Cancel = true; return; } // 保存成功后关闭 if (this._isSaving) { this.DialogResult = DialogResult.OK; base.OnClosing(e); return; } this._isClosing = true; try { // 画面数据有更改 if (this.Dirty) { DialogResult dr = this.ShowMessageOnDirtyClose(); // 关闭前保存 if (dr == DialogResult.Yes) { // 保存成功 if (this.SetData()) { this._isDirty = false; this.DialogResult = DialogResult.OK; } // 保存失败 else { e.Cancel = true; return; } } // 关闭不保存 else if (dr == DialogResult.No) { //if (this.DialogResult == DialogResult.None) //{ // this.DialogResult = DialogResult.Cancel; //} } // 取消关闭 else //if (dr == DialogResult.Cancel) { e.Cancel = true; return; } } if (this.DialogResult == DialogResult.None) { this.DialogResult = DialogResult.Cancel; } base.OnClosing(e); } finally { this._isClosing = false; } } /// /// 窗体加载时发生。 /// /// protected override void OnLoad(EventArgs e) { this.DialogResult = DialogResult.None; this._loadCount++; if (this._loadCount == 1) { this.InitForm(); } if (!this.DesignMode) { if (!this.LoadForm()) { this._isDirty = false; this.Close(); return; } } base.OnLoad(e); this._isDirty = false; try { // TODO 临时 //datagridview控件设置保存 System.Collections.Generic.List controls = this.GetControls(this, typeof(Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView)); foreach (Dongke.IBOSS.PRD.Basics.BaseControls.C_DataGridView dgv in controls) { if (dgv.IsSaveDataGridViewSetting) { Dongke.IBOSS.PRD.Basics.Library.GridSettingManager.InitializeGridSetting(dgv, this.Name + dgv.Name); } } } catch /*(Exception ex)*/ { //Dongke.IBOSS.MBC.Basics.Library.OutputLog.TraceLog( Dongke.IBOSS.MBC.Basics.Library.LogPriority.Error, // "Dongke.WinForm.Controls.FormBase", "SaveGridSetting", ex.Message, logFilePath); } } /// /// TODO 临时 /// /// /// /// private System.Collections.Generic.List GetControls(Control topControl, Type type) { if (topControl == null) { return GetControls(this, type); } System.Collections.Generic.List list = new System.Collections.Generic.List(); foreach (Control control in topControl.Controls) { if (type == null || type.Equals(control.GetType())) { list.Add(control); } list.AddRange(GetControls(control, type)); } return list; } #endregion #region 事件处理 #endregion #region 重写方法 #endregion #region 公有方法 #region Set /// /// 点击保存或确定按钮时调用。 /// /// 操作结果 public virtual bool SetData() { Control ac = this.ActiveControl; this.txtFoucs.Focus(); bool result = false; // 验证画面数据有效性 result = this.CheckInputData(); if (!result) { return result; } // 保存数据到服务端 result = this.SetDataToOther(); if (!result) { //this.ShowMessageOnSetDefeated(); ac.Focus(); return result; } // 关闭画面的保存 if (this._isClosing) { if (this._formType != FormType.Select) { this.ShowMessageOnSetSucceed(); } ac.Focus(); return result; } // 新建、复制成功后 if (this._formType == FormType.Add || this._formType == FormType.Copy) { // 是否继续操作 if (this.ShowMessageOnAddSucceed()) { this.RefreshData(); this._isDirty = false; ac.Focus(); return result; } } else if (this._formType != FormType.Select) { this.ShowMessageOnSetSucceed(); } this._isSaving = true; this.Close(); this._isSaving = false; return result; } /// /// 窗体中数据保存后,需要继续操作,并初始化窗体时调用。 /// public virtual void RefreshData() { this.ClearConditions(); this.ClearQueryResults(); this.ssrAsyncStatusStrip.ClearCommTimes(); base.SelectNextControl(null, true, true, true, false); this._isDirty = false; } #endregion #region Query /// /// 点击查询按钮时调用。 /// /// 操作结果 public virtual bool QueryData() { bool result = false; // 验证查询条件有效性 result = this.CheckQueryConditions(); if (!result) { return result; } this.ClearQueryResults(); result = this.QueryDataFromOther(); //if (!result) //{ // this.ShowMessageOnQueryDefeated(); //} return result; } /// /// 清除查询条件 /// public virtual void ClearConditions() { } /// /// 清除查询结果 /// public virtual void ClearQueryResults() { } #endregion #region 异步处理 /// /// 窗体的异步处理 /// /// 异步方法 /// 返回值 /// 处理结果:true处理成功,false处理失败 public bool DoAsync(Func method, out TResult result) { result = default(TResult); bool asyncResult = false; if (this._doAsync) { return asyncResult; } CancelEventArgs ce = new CancelEventArgs(); this.OnAsyncBegin(ce); if (ce.Cancel) { return asyncResult; } try { this._cancelAsync = false; this._doAsync = true; this._canClose = false; this.StartProgress(); IAsyncResult iAsyncResult = method.BeginInvoke(null, null); while (!iAsyncResult.IsCompleted) { if (this._cancelAsync) { return asyncResult; } Application.DoEvents(); Thread.Sleep(1); } result = method.EndInvoke(iAsyncResult); asyncResult = true; } finally { this._doAsync = false; this._canClose = true; this.EndProgress(); AsyncEndEventArgs e = new AsyncEndEventArgs(asyncResult, result); this.OnAsyncEnd(e); asyncResult = e.AsyncResult; } return asyncResult; } /// /// 取消异步处理。 /// public void CancelAsync() { if (this._doAsync) { this._cancelAsync = true; } } #endregion /* #region 异步处理(不锁定窗体) /// /// 窗体的异步处理(不锁定窗体) /// /// 返回值类型 /// 异步方法 /// 回调方法 /// 方法扩展标识 /// 方法标识 public static IAsyncInvoker DoAsync(Func method, Action callback, string code = null) { return AsyncFactory.Invoke(method, callback, code); } /// /// 取消异步 /// /// 返回值类型 /// 异步方法 /// 方法扩展标识 /// 是否成功取消 public static bool Cancel(Func method, string code = null) { return AsyncFactory.Cancel(method, code); } /// /// 取消异步 /// /// 方法标识 /// 是否成功取消 public static bool Cancel(string methodCode) { return AsyncFactory.Cancel(methodCode); } /// /// 获取异步是否正在处理 /// /// 返回值类型 /// 异步方法 /// 方法扩展标识 /// 是否正在处理 public static bool IsDoing(Func method, string code = null) { return AsyncFactory.IsDoing(method, code); } /// /// 获取异步是否正在处理 /// /// 方法标识 /// 是否正在处理 public static bool IsDoing(string methodCode) { return AsyncFactory.IsDoing(methodCode); } /// /// 获取方法标识 /// /// 返回值类型 /// 异步方法 /// 方法扩展标识 /// 方法标识 public static string GetMethodCode(Func method, string code = null) { return AsyncFactory.GetMethodCode(method, code); } #endregion */ /// /// 向用户显示具有指定所有者的窗体。 /// /// 表示将拥有模式对话框的顶级窗口 public virtual new void Show(IWin32Window owner) { base.Show(owner); this.ActivateForm(); } /// /// 向用户显示具有指定所有者的窗体。 /// public virtual new void Show() { base.Show(); this.ActivateForm(); } /// /// 激活窗体 /// public void ActivateForm() { this.Visible = true; if (this.WindowState == FormWindowState.Minimized) { this.WindowState = this._formWindowState; } base.Activate(); } #endregion #region 保护方法 /// /// 设置异步处理开始状态 /// protected virtual void StartProgress() { this._doFocus = true; this.BeginAsyncControls(this); this.ssrAsyncStatusStrip.Communicate = true; } /// /// 设置异步处理结束状态 /// protected virtual void EndProgress() { this.ssrAsyncStatusStrip.Communicate = false; this.EndAsyncControls(this); } #region NotImplemented #region Form /// /// 窗体加载前调用(设置Form.Text、按钮等控件Text等)。 /// protected virtual void InitForm() { } /// /// 窗体加载时调用(获取窗体初始化数据等)。 /// protected virtual bool LoadForm() { return true; } #endregion #region Close /// /// 验证窗体中数据是否改变。 /// /// 数据被更改true,其他false protected virtual bool CheckDirty() { return false; } /// /// 关闭数据有改变的画面时,提示消息 /// protected virtual DialogResult ShowMessageOnDirtyClose() { return DialogResult.Yes; } #endregion #region Set /// /// 验证画面输入项目 /// /// 验证通过true,其他false protected virtual bool CheckInputData() { return true; } /// /// 保存或设置数据到其他位置(其他画面或DB) /// /// 保存或设置成功true,其他false protected virtual bool SetDataToOther() { return true; } /// /// 保存或设置数据成功后提示消息 /// protected virtual void ShowMessageOnSetSucceed() { } /// /// 保存或设置数据成功后提示消息(新建或复制时,询问是否继续操作) /// /// 继续操作true,其他false protected virtual bool ShowMessageOnAddSucceed() { return true; } ///// ///// 保存或设置数据失败后提示消息 ///// //protected virtual void ShowMessageOnSetDefeated() //{ //} #endregion #region Query /// /// 验证查询条件。 /// /// 验证通过true,其他false protected virtual bool CheckQueryConditions() { return true; } /// /// 查询数据。 /// /// 验证通过true,其他false protected virtual bool QueryDataFromOther() { return true; } ///// ///// 查询失败后提示消息 ///// //protected virtual void ShowMessageOnQueryDefeated() //{ //} #endregion #endregion #endregion #region 私有方法 // todo 控件混用补丁。 Control _fouced = null; /// /// 异步开始设置控件状态 /// /// private void BeginAsyncControls(Control control) { if (control == null) { return; } if (control is IAsyncControl) { // todo 修改为把控件传入 (control as IAsyncControl).BeginAsync(ref this._doFocus); if (!this._doFocus) { this.txtFoucs.Focus(); } return; } else { // todo 控件混用补丁。 if (control is DataGridView) { if (control.Focused) { this._fouced = control; this.txtFoucs.Focus(); } control.Enabled = false; return; } if (control.Controls == null || control.Controls.Count == 0) { //control.Enabled = false; return; } foreach (Control item in control.Controls) { this.BeginAsyncControls(item); } } } /// /// 异步结束设置控件状态 /// /// private void EndAsyncControls(Control control) { if (control == null) { return; } if (control is IAsyncControl) { (control as IAsyncControl).EndAsync(); return; } else { // todo 控件混用补丁。 if (control is DataGridView) { control.Enabled = true; if (this._fouced == control) { this._fouced = null; control.Focus(); } return; } if (control.Controls == null || control.Controls.Count == 0) { //control.Enabled = false; return; } foreach (Control item in control.Controls) { this.EndAsyncControls(item); } } } /// /// 设置是否在控件的右下角显示大小调整手柄。 /// private void SetStatusSizingGrip() { switch (base.FormBorderStyle) { case FormBorderStyle.Sizable: case FormBorderStyle.SizableToolWindow: this.ssrAsyncStatusStrip.SizingGrip = true; break; default: this.ssrAsyncStatusStrip.SizingGrip = false; break; } } #endregion } }