diff --git a/插件库/Lskj.Control/TabControlEx.cs b/插件库/Lskj.Control/TabControlEx.cs index 8a8cdb4..5718b74 100644 --- a/插件库/Lskj.Control/TabControlEx.cs +++ b/插件库/Lskj.Control/TabControlEx.cs @@ -1806,7 +1806,7 @@ namespace Lskj.Control Task sourceColumnByDatabaseTask = cachesDic.AddTask(gridEx, "CustomColumnByDatabase", new Task(() => { string customColumKey = model.GridCustomColumnKey; - return gridEx.GridView.GetCustomColumnByDatabase(customColumKey); + return GridExtend.GetCustomColumnByDatabase(customColumKey); })); Task baseGridRightMenusTask = cachesDic.AddTask(gridEx, "BaseGridRightMenus", new Task(() => { diff --git a/插件库/Lskj.PubBill/BillModule.cs b/插件库/Lskj.PubBill/BillModule.cs index d6b186c..1af102e 100644 --- a/插件库/Lskj.PubBill/BillModule.cs +++ b/插件库/Lskj.PubBill/BillModule.cs @@ -219,6 +219,12 @@ namespace Lskj.PubBill /// public Dictionary BillModuleModelDic = new Dictionary(); /// + /// 当前单据在 UI 线程创建的来源明细页。部分非首来源页不会立即加入 + /// TabControl,模块永久关闭时需要按所属范围释放这些脱离父级的页面。 + /// + private readonly HashSet _ownedSourceDetailPages = + new HashSet(); + /// /// 主表动态生成的日期列 /// public List DateColumnList = new List(); @@ -398,6 +404,27 @@ namespace Lskj.PubBill private void DisposeDetachedOwnedSourceControls() { + // 非首个来源明细页由当前 BillModule 创建,但不会立即加入底部页签。 + // 只释放本模块明确登记且仍未挂到任何父容器的页面;已挂载页面继续 + // 交给其所在窗体的正常 Dispose 链,避免影响其他未关闭模块。 + foreach (XtraTabPage detailPage in _ownedSourceDetailPages.ToList()) + { + if (detailPage == null || detailPage.IsDisposed || + !IsDetachedOwnedSourceDetailPage(detailPage)) + { + continue; + } + + try + { + detailPage.Dispose(); + } + catch (Exception exception) + { + Debug.WriteLine("释放单据来源明细页失败:" + exception); + } + } + // 来源页签切换会通过 Controls.Clear 临时摘下非当前页的控件。 // 模块永久关闭时只处理当前 BillModuleModelDic 明确登记的三个 // 顶层来源控件,不扫描其他窗体或全局控件树。释放父控件可让 @@ -435,6 +462,29 @@ namespace Lskj.PubBill } } + private bool IsDetachedOwnedSourceDetailPage(XtraTabPage detailPage) + { + if (detailPage == null) + return false; + + try + { + if (tb_buttom != null && tb_buttom.TabControlObj != null && + tb_buttom.TabControlObj.TabPages.Contains(detailPage)) + { + return false; + } + + // 明确存在父级表示页面已经挂入某个活动控件树,不由当前模块 + // 的“孤立页面”清理路径处理。 + return detailPage.Parent == null; + } + catch (ObjectDisposedException) + { + return true; + } + } + private static void AddOwnedSourceControl( HashSet target, object sourceControl) @@ -445,6 +495,24 @@ namespace Lskj.PubBill target.Add(control); } + private static void AttachCachedTask( + Dictionary cachesDic, + object cacheOwner, + string cacheKey, + object control, + string controlKey) + { + if (cachesDic == null || cacheOwner == null || control == null || + cachesDic.GetTask(control, controlKey) != null) + { + return; + } + + Task task = cachesDic.GetTask(cacheOwner, cacheKey); + if (task != null) + cachesDic.AddTask(control, controlKey, task); + } + private bool IsDetachedFromModuleDisposeChain( System.Windows.Forms.Control control) { @@ -704,6 +772,7 @@ namespace Lskj.PubBill model.SourceModel = null; } BillModuleModelDic.Clear(); + _ownedSourceDetailPages.Clear(); pageNumKey.Clear(); foreach (Dictionary rows in ToWithdrawRows) if (rows != null) @@ -952,16 +1021,8 @@ namespace Lskj.PubBill } return controls; })); - Task controlObjTask = cachesDic.AddTask(this, "ControlObj", new Task(() => - { - MyControl myControl = new MyControl() { Model = dynamicModel }; - myControl.MrpClickMenus = new DataTable(); - myControl.OtherParams = dynamicModel.OtherParams(); - cachesDic.AddTask(myControl, "DynamicModel", dynamicModelTask); - cachesDic.AddTask(myControl, "ControlsTable", controlLocationTask); - myControl.GetControlDataCaches(cachesDic); - return myControl;//主表控件 - })); + // MyControl 持有 WinForms Timer。后台预加载只取得控件配置数据, + // MyControl 及其实际编辑控件统一在真正的 UI 线程创建。 Task addGroupDataTask = cachesDic.AddTask(this, "AddGroupData", new Task(() => { return BaseModuleImpl.GetAddGroupData(billModel.FormKey);//获取主信息分组数据 @@ -1023,12 +1084,13 @@ namespace Lskj.PubBill })); cachesDic.AddTask(tb_buttom, "DynamicModel", dynamicModelTask); cachesDic.AddTask(tb_buttom, "Details", detailTask); - tb_buttom.GetDataCaches(cachesDic); + // TabControlEx.GetDataCaches 会创建 Grid、ModuleGrid、浏览器等 + // WinForms/DevExpress 控件。这里只预取 Details,实际控件预创建 + // 延后到 InitializeBillSource 的 UI 线程执行。 Task initSourcesTask = cachesDic.AddTask(this, "InitSourcesTask", new Task(() => { Hashtable htTable = sourcesTask.Result; DataTable masterTable = htTable["master"] as DataTable; - DataTable detailTable = htTable["detail"] as DataTable; for (int i = 0; i < masterTable.Rows.Count; i++) { DataRow sourceModelRow = masterTable.Rows[i]; @@ -1039,151 +1101,75 @@ namespace Lskj.PubBill { return BaseModuleImpl.GetCustomQueryFields(model.FormKey); })); - #region 加载来源表头 - GridControlEx gridControl = null; - TreeViewEx treeView = null; + + // 后台阶段只加载数据,不构造任何 WinForms/DevExpress + // 对象。缓存以 BillModuleModel 为所有者,UI 创建实际控件 + // 后再把需要的任务绑定到该控件。 if (model.SourceType == 1) { - // 来源为树类型 - treeView = new TreeViewEx(); - billModuleModel.SourceControl = treeView; - Task bindTreeTableTask = cachesDic.AddTask(treeView, "BindTreeTable", new Task(() => + cachesDic.AddTask(billModuleModel, "BindTreeTable", new Task(() => { return BaseImpl.GetDataTableResult(model.SourceSql); })); } - else if (model.SourceType == 5) - { - model.ChangeSourceType(2);//单据来源显示条数 - } - else if (model.SourceType == 3 || model.SourceType == 4) - { - gridControl = new TreeGridControlEx(); - billModuleModel.SourceControl = gridControl; - Task sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task(() => - { - return BillImpl.GetSourceColumns(model.Id); - })); - Task sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task(() => - { - return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); - })); - Task sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); - })); - } else { - // 来源为表格类型 - gridControl = new GridControlEx(); - billModuleModel.SourceControl = gridControl; - Task sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task(() => + if (model.SourceType == 5) + model.ChangeSourceType(2);//单据来源显示条数 + + cachesDic.AddTask(billModuleModel, "SourceColumns", new Task(() => { return BillImpl.GetSourceColumns(model.Id); })); - //创建表格列 - cachesDic.AddTask(gridControl, "DynamicModel", dynamicModelTask); - gridControl.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceGridView + model.FormKey); - Task sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase( + GridCustomColumnStruct.BillSourceGridView + model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceBaseGridRowColors", new Task(() => { return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); })); - Task sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceBaseGridRightMenus", new Task(() => { return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); })); } - #endregion - #region 加载来源明细 - // The concrete source-detail control is selected below. - // Do not allocate a temporary GridControlEx first: replacing - // that unattached instance leaves its GridView subscribed to - // DevExpress global localizer events. - GridControlEx gridDetail = null; - if (!string.IsNullOrWhiteSpace(model.DetailModeCode)) - { + if (string.IsNullOrWhiteSpace(model.DetailModeCode)) + { + cachesDic.AddTask(billModuleModel, "SourceDetailCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase( + GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRowColors", new Task(() => + { + return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRightMenus", new Task(() => + { + return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); + })); + + if (!string.IsNullOrEmpty(model.SourceDetailsDetailsSql)) + { + cachesDic.AddTask(billModuleModel, "DetailDetails", new Task(() => + { + return BaseModuleImpl.getDetail_Details(model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailDetailsCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase(string.Empty); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailDetailsBaseGridRightMenus", new Task(() => + { + return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey); + })); + } } - else - { - if (model.sourceDetailType.Equals("1")) - { - //明细为树表格 - gridDetail = new TreeGridControlEx(); - billModuleModel.SourceDetailControl = gridDetail; - //创建表格列 - cachesDic.AddTask(gridDetail, "DynamicModel", dynamicModelTask); - gridDetail.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - Task detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task(() => - { - return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); - })); - Task detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); - })); - } - else - { - gridDetail = new GridControlEx(); - billModuleModel.SourceDetailControl = gridDetail; - //创建表格列 - cachesDic.AddTask(gridDetail, "DynamicModel", dynamicModelTask); - gridDetail.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - Task detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task(() => - { - return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); - })); - Task detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); - })); - //明细的明细(明细分成左右2个) - if (!string.IsNullOrEmpty(model.SourceDetailsDetailsSql)) - { - GridControlEx gridDetail_Details = new GridControlEx(); - billModuleModel.SourceDetailDetailControl = gridDetail_Details; - //创建只读列 - Task detailDetailsTask = cachesDic.AddTask(gridDetail_Details, "DetailDetails", new Task(() => - { - return BaseModuleImpl.getDetail_Details(model.FormKey); - })); - //创建表格列 - cachesDic.AddTask(gridDetail_Details, "DynamicModel", dynamicModelTask); - gridDetail_Details.GetDataCaches(cachesDic); - Task detailDetailsGridRightMenusTask = cachesDic.AddTask(gridDetail_Details, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey); - })); - } - } - } - - - #endregion BillModuleModelDic.Add(sourceModelRow, billModuleModel); - #region 加载来源条件 - Task searchControlTask = cachesDic.AddTask(sourceModelRow, "SearchControl", new Task(() => - { - DataTable controls = customQueryFieldsTask.Result; - MyControl searchControl = null; - if (model.SourceType != 1 || (controls != null && controls.Rows.Count > 0)) - { - // 创建自定义条件 - string searchSql = model.SourceType == 1 ? Regex.Replace(model.DetailSql, "{speciesno}", "", RegexOptions.IgnoreCase) : model.SourceSql; - searchControl = new MyControl(searchSql, gridControl == null ? gridDetail : gridControl, treeView); - searchControl.Model = dynamicModel; - searchControl.MrpClickMenus = new DataTable(); - searchControl.OtherParams = dynamicModel.OtherParams(); - cachesDic.AddTask(searchControl, "DynamicModel", dynamicModelTask); - cachesDic.AddTask(searchControl, "ControlsTable", customQueryFieldsTask); - searchControl.GetSearchDataCaches(cachesDic); - } - return searchControl; - })); - #endregion } return true; })); @@ -1723,7 +1709,20 @@ namespace Lskj.PubBill } if (!dataCaches.GetValue(this, "ControlObj", out ControlObj)) { + // MyControl 持有 WinForms Timer,必须在当前 UI 线程创建。 this.ControlObj = new MyControl() { Model = SysModel };//主表控件 + this.ControlObj.MrpClickMenus = new DataTable(); + this.ControlObj.OtherParams = this.SysModel.OtherParams(); + if (dataCaches != null) + { + dataCaches.AddTask(this.ControlObj, "DynamicModel", + new Task(() => this.SysModel)); + dataCaches.AddTask(this.ControlObj, "ControlsTable", + new Task(() => controls)); + // 这里只启动默认值、查询 SQL、ControlModel 等数据任务, + // 实际 WinForms 编辑控件仍由下面的 InitControl 创建。 + this.ControlObj.GetControlDataCaches(dataCaches); + } } //this.ControlObj = new MyControl();//// 主表控件 @@ -2431,6 +2430,14 @@ namespace Lskj.PubBill this.xtc_left_container.TabPages.Clear(); Dictionary dataCaches = SysModel != null ? SysModel.DataCaches : null; + if (dataCaches != null && + dataCaches.GetTask(tb_buttom, "DynamicModel") != null && + dataCaches.GetTask>(tb_buttom, "Details") != null) + { + // 该方法会预创建附加页控件,必须在 UI 线程执行;其内部查询 + // 任务仍由原有 TaskSchedulerUtil 并行调度。 + tb_buttom.GetDataCaches(dataCaches); + } if (!dataCaches.GetValue(this, "Details", out List attachModels)) { attachModels = GetAttachTabs(); @@ -2532,11 +2539,11 @@ namespace Lskj.PubBill //获取主表列 SourceMainColumns = BaseModuleImpl.GetBaseGridColumns(sysModel.ModeCode); - if (!dataCaches.GetValue(gridControl, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); } - if (!dataCaches.GetValue(gridControl, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); } @@ -2557,7 +2564,10 @@ namespace Lskj.PubBill gridControl.ExportPermission = this.BillModel.ExportPermission; } - gridControl.SetReadOnlyColumns(SourceMainColumns, GridCustomColumnStruct.BillSourceGridView + model.FormKey); + AttachCachedTask(dataCaches, billModuleModel, + "SourceCustomColumnByDatabase", gridControl, + "CustomColumnByDatabase"); + gridControl.SetReadOnlyColumns(SourceMainColumns, GridCustomColumnStruct.BillSourceGridView + model.FormKey); gridControl.SetGridRowColors(dtBaseGridRowColors); gridControl.SetGridRightMenus(dtBaseGridRightMenus, this.SysModel, OnGridControlRightCallback); @@ -2643,7 +2653,7 @@ namespace Lskj.PubBill treeView.Dock = DockStyle.Fill; treeView.TreeNodeKeyField = model.SourceKeyField; treeView.TreeNodeTextField = model.SourceResult; - if (!dataCaches.GetValue(treeView, "BindTreeTable", out DataTable bindTreeTable)) + if (!dataCaches.GetValue(billModuleModel, "BindTreeTable", out DataTable bindTreeTable)) { bindTreeTable = BaseImpl.GetDataTableResult(model.SourceSql); } @@ -2667,15 +2677,15 @@ namespace Lskj.PubBill gridControl.BorderStyle = System.Windows.Forms.BorderStyle.None; gridControl.Model = this.SysModel; - if (!dataCaches.GetValue(gridControl, "SourceColumns", out DataTable dtSourceColumns)) + if (!dataCaches.GetValue(billModuleModel, "SourceColumns", out DataTable dtSourceColumns)) { dtSourceColumns = BillImpl.GetSourceColumns(model.Id); } - if (!dataCaches.GetValue(gridControl, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); } - if (!dataCaches.GetValue(gridControl, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); } @@ -2685,6 +2695,9 @@ namespace Lskj.PubBill //父节点编号 if (!string.IsNullOrWhiteSpace(model.SourceParentFieldName)) (gridControl as TreeGridControlEx).TreeListObj.ParentFieldName = model.SourceParentFieldName; + AttachCachedTask(dataCaches, billModuleModel, + "SourceCustomColumnByDatabase", gridControl, + "CustomColumnByDatabase"); gridControl.SetReadOnlyColumns(dtSourceColumns, GridCustomColumnStruct.BillSourceGridView + model.FormKey); gridControl.SetGridRowColors(dtBaseGridRowColors); //gridControl.SetGridRightMenus(dtBaseGridRightMenus, this.SysModel, OnGridControlRightCallback); @@ -2731,18 +2744,21 @@ namespace Lskj.PubBill { gridControl.GridView.OptionsView.ShowAutoFilterRow = true; } - if (!dataCaches.GetValue(gridControl, "SourceColumns", out DataTable dtSourceColumns)) + if (!dataCaches.GetValue(billModuleModel, "SourceColumns", out DataTable dtSourceColumns)) { dtSourceColumns = BillImpl.GetSourceColumns(model.Id); } - if (!dataCaches.GetValue(gridControl, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); } - if (!dataCaches.GetValue(gridControl, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); } + AttachCachedTask(dataCaches, billModuleModel, + "SourceCustomColumnByDatabase", gridControl, + "CustomColumnByDatabase"); gridControl.SetReadOnlyColumns(dtSourceColumns, GridCustomColumnStruct.BillSourceGridView + model.FormKey); gridControl.SetGridRowColors(dtBaseGridRowColors); gridControl.SetGridRightMenus(dtBaseGridRightMenus, this.SysModel, OnGridControlRightCallback); @@ -2789,6 +2805,7 @@ namespace Lskj.PubBill #region 加载来源明细 XtraTabPage tabDetail = new XtraTabPage(); + _ownedSourceDetailPages.Add(tabDetail); if (SystemInfo.Instance.GridRowFontSize > 0) { @@ -2894,12 +2911,15 @@ namespace Lskj.PubBill gridDetail = sourceDetailControl != null ? (TreeGridControlEx)sourceDetailControl : new TreeGridControlEx(); gridDetail.Model = this.SysModel; gridDetail.Dock = DockStyle.Fill; + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailCustomColumnByDatabase", gridDetail, + "CustomColumnByDatabase"); gridDetail.SetReadOnlyColumns(detailColumns == null || detailColumns.Length == 0 ? new DataTable() : detailColumns.CopyToDataTable(), GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - if (!dataCaches.GetValue(gridDetail, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); } - if (!dataCaches.GetValue(gridDetail, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); } @@ -2933,17 +2953,20 @@ namespace Lskj.PubBill gridDetail = sourceDetailControl != null ? (GridControlEx)sourceDetailControl : new GridControlEx(); gridDetail.Model = this.SysModel; gridDetail.Dock = DockStyle.Fill; + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailCustomColumnByDatabase", gridDetail, + "CustomColumnByDatabase"); gridDetail.SetReadOnlyColumns(detailColumns == null || detailColumns.Length == 0 ? new DataTable() : detailColumns.CopyToDataTable(), GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); if (model.DetailedLoadFilter) { gridDetail.GridView.OptionsView.ShowAutoFilterRow = true; } - if (!dataCaches.GetValue(gridDetail, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); } - if (!dataCaches.GetValue(gridDetail, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); } @@ -2963,17 +2986,21 @@ namespace Lskj.PubBill gridDetail_Details.Model = this.SysModel; gridDetail_Details.Dock = DockStyle.Fill; //创建只读列 - if (!dataCaches.GetValue(gridDetail_Details, "Detail_Details", out DataTable dataTable)) + if (!dataCaches.GetValue(billModuleModel, "DetailDetails", out DataTable dataTable)) { dataTable = BaseModuleImpl.getDetail_Details(model.FormKey); } + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailDetailsCustomColumnByDatabase", + gridDetail_Details, "CustomColumnByDatabase"); gridDetail_Details.SetReadOnlyColumns(dataTable); //设置右键 - if (!dataCaches.GetValue(gridDetail_Details, "BaseGridRightMenus", out DataTable dttBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailDetailsBaseGridRightMenus", out DataTable dttBaseGridRightMenus)) { dttBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey); } gridDetail_Details.SetGridRightMenus(dttBaseGridRightMenus, this.SysModel, OnGridDetailRightMenuCallback); + billModuleModel.SourceDetailDetailControl = gridDetail_Details; //明细点击 更新 明细的明细 gridDetail.GridView.FocusedRowObjectChanged += GridView_FocusedRowObjectChanged; gridDetail.GridView.Tag = model.SourceDetailsDetailsSql; @@ -3074,6 +3101,11 @@ namespace Lskj.PubBill #endregion + billModuleModel.SourceControl = + treeView != null ? (object)treeView : gridControl; + billModuleModel.SourceDetailControl = gridDetail; + BillModuleModelDic[sourceModelRow] = billModuleModel; + #region 加载来源条件 if (model.SourceType == 1 && (controls == null || controls.Rows.Count == 0)) { @@ -3095,9 +3127,24 @@ namespace Lskj.PubBill string searchSql = model.SourceType == 1 ? Regex.Replace(model.DetailSql, "{speciesno}", "", RegexOptions.IgnoreCase) : model.SourceSql; //searchSql = ReplaceHelper.ReplaceParam(searchSql); PanelControl searchPanel = new PanelControl(); - if (!dataCaches.GetValue(sourceModelRow, "SearchControl", out MyControl searchControl)) + MyControl searchControl = + new MyControl(searchSql, + gridControl == null ? gridDetail : gridControl, + treeView) { - searchControl = new MyControl(searchSql, gridControl == null ? gridDetail : gridControl, treeView); + Model = this.SysModel, + MrpClickMenus = new DataTable(), + OtherParams = this.SysModel.OtherParams() + }; + if (dataCaches != null) + { + dataCaches.AddTask(searchControl, "DynamicModel", + new Task(() => this.SysModel)); + dataCaches.AddTask(searchControl, "ControlsTable", + new Task(() => controls)); + // 查询条件的默认值和 ControlModel 继续在旧调度器中并行 + // 准备,WinForms 编辑控件由 InitSearchControl 在 UI 创建。 + searchControl.GetSearchDataCaches(dataCaches); } searchControl.OnSearchBeforeCallBack += new SearchEventHandler(OnSearchBefore); searchControl.OnSearchAfterCallBack += new EventHandler(OnSearchAfterd); @@ -3118,7 +3165,6 @@ namespace Lskj.PubBill searchPanel.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder; searchPanel.BackColor = Color.Transparent; searchPanel.Parent = tabPage; - searchControl.OtherParams = this.SysModel.OtherParams(); searchPanel.Height = searchControl.InitSearchControl(controls, searchPanel); unionModel.SearchObj = searchControl; } diff --git a/插件库/Lskj.PubBillManagement/BillModule.cs b/插件库/Lskj.PubBillManagement/BillModule.cs index bb2b6de..912ef9c 100644 --- a/插件库/Lskj.PubBillManagement/BillModule.cs +++ b/插件库/Lskj.PubBillManagement/BillModule.cs @@ -40,6 +40,24 @@ namespace Lskj.PubBillManagement { public partial class BillModule : UserControl { + private static void AttachCachedTask( + Dictionary cachesDic, + object cacheOwner, + string cacheKey, + object control, + string controlKey) + { + if (cachesDic == null || cacheOwner == null || control == null || + cachesDic.GetTask(control, controlKey) != null) + { + return; + } + + Task task = cachesDic.GetTask(cacheOwner, cacheKey); + if (task != null) + cachesDic.AddTask(control, controlKey, task); + } + /// /// 是否为初始化创建 /// @@ -418,12 +436,13 @@ namespace Lskj.PubBillManagement })); cachesDic.AddTask(tb_buttom, "DynamicModel", dynamicModelTask); cachesDic.AddTask(tb_buttom, "Details", detailTask); - tb_buttom.GetDataCaches(cachesDic); + // TabControlEx.GetDataCaches 会创建 Grid、ModuleGrid、浏览器等 + // WinForms/DevExpress 控件,延后到 InitializeBillSource + // 在 UI 线程执行。 Task initSourcesTask = cachesDic.AddTask(this, "InitSourcesTask", new Task(() => { Hashtable htTable = sourcesTask.Result; DataTable masterTable = htTable["master"] as DataTable; - DataTable detailTable = htTable["detail"] as DataTable; for (int i = 0; i < masterTable.Rows.Count; i++) { DataRow sourceModelRow = masterTable.Rows[i]; @@ -434,137 +453,75 @@ namespace Lskj.PubBillManagement { return BaseModuleImpl.GetCustomQueryFields(model.FormKey); })); - #region 加载来源表头 - GridControlEx gridControl = null; - TreeViewEx treeView = null; + + // 后台阶段只加载数据,不构造任何 WinForms/DevExpress + // 对象。缓存以 BillModuleModel 为所有者,UI 创建实际 + // 控件后再绑定需要的任务。 if (model.SourceType == 1) { - // 来源为树类型 - treeView = new TreeViewEx(); - billModuleModel.SourceControl = treeView; - Task bindTreeTableTask = cachesDic.AddTask(treeView, "BindTreeTable", new Task(() => + cachesDic.AddTask(billModuleModel, "BindTreeTable", new Task(() => { return BaseImpl.GetDataTableResult(model.SourceSql); })); } - else if (model.SourceType == 5) - { - model.ChangeSourceType(2);//单据来源显示条数 - } - else if (model.SourceType == 3 || model.SourceType == 4) - { - gridControl = new TreeGridControlEx(); - billModuleModel.SourceControl = gridControl; - Task sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task(() => - { - return BillImpl.GetSourceColumns(model.Id); - })); - Task sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task(() => - { - return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); - })); - Task sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); - })); - } else { - // 来源为表格类型 - gridControl = new GridControlEx(); - billModuleModel.SourceControl = gridControl; - Task sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task(() => + if (model.SourceType == 5) + model.ChangeSourceType(2);//单据来源显示条数 + + cachesDic.AddTask(billModuleModel, "SourceColumns", new Task(() => { return BillImpl.GetSourceColumns(model.Id); })); - //创建表格列 - cachesDic.AddTask(gridControl, "DynamicModel", dynamicModelTask); - gridControl.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceGridView + model.FormKey); - Task sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase( + GridCustomColumnStruct.BillSourceGridView + model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceBaseGridRowColors", new Task(() => { return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); })); - Task sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceBaseGridRightMenus", new Task(() => { return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); })); } - #endregion - #region 加载来源明细 - GridControlEx gridDetail = new GridControlEx(); - if (model.sourceDetailType.Equals("1")) + + if (string.IsNullOrWhiteSpace(model.DetailMenuCode)) { - //明细为树表格 - gridDetail = new TreeGridControlEx(); - billModuleModel.SourceDetailControl = gridDetail; - //创建表格列 - cachesDic.AddTask(gridDetail, "DynamicModel", dynamicModelTask); - gridDetail.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - Task detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceDetailCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase( + GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRowColors", new Task(() => { return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); })); - Task detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRightMenus", new Task(() => { return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); })); - } - else - { - gridDetail = new GridControlEx(); - billModuleModel.SourceDetailControl = gridDetail; - //创建表格列 - cachesDic.AddTask(gridDetail, "DynamicModel", dynamicModelTask); - gridDetail.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - Task detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task(() => - { - return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); - })); - Task detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task(() => - { - return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); - })); - //明细的明细(明细分成左右2个) if (!string.IsNullOrEmpty(model.SourceDetailsDetailsSql)) { - GridControlEx gridDetail_Details = new GridControlEx(); - billModuleModel.SourceDetailDetailControl = gridDetail_Details; - //创建只读列 - Task detailDetailsTask = cachesDic.AddTask(gridDetail_Details, "DetailDetails", new Task(() => + cachesDic.AddTask(billModuleModel, "DetailDetails", new Task(() => { return BaseModuleImpl.getDetail_Details(model.FormKey); })); - //创建表格列 - cachesDic.AddTask(gridDetail_Details, "DynamicModel", dynamicModelTask); - gridDetail_Details.GetDataCaches(cachesDic); - Task detailDetailsGridRightMenusTask = cachesDic.AddTask(gridDetail_Details, "BaseGridRightMenus", new Task(() => + cachesDic.AddTask(billModuleModel, "SourceDetailDetailsCustomColumnByDatabase", new Task(() => + { + return GridExtend.GetCustomColumnByDatabase(string.Empty); + })); + cachesDic.AddTask(billModuleModel, "SourceDetailDetailsBaseGridRightMenus", new Task(() => { return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey); })); } } - #endregion + BillModuleModelDic.Add(sourceModelRow, billModuleModel); - #region 加载来源条件 - Task searchControlTask = cachesDic.AddTask(sourceModelRow, "SearchControl", new Task(() => - { - DataTable controls = customQueryFieldsTask.Result; - MyControl searchControl = null; - if (model.SourceType != 1 || (controls != null && controls.Rows.Count > 0)) - { - // 创建自定义条件 - string searchSql = model.SourceType == 1 ? Regex.Replace(model.DetailSql, "{speciesno}", "", RegexOptions.IgnoreCase) : model.SourceSql; - searchControl = new MyControl(searchSql, gridControl == null ? gridDetail : gridControl, treeView); - searchControl.Model = dynamicModel; - searchControl.OtherParams = dynamicModel.OtherParams(); - cachesDic.AddTask(searchControl, "DynamicModel", dynamicModelTask); - cachesDic.AddTask(searchControl, "ControlsTable", customQueryFieldsTask); - searchControl.GetSearchDataCaches(cachesDic); - } - return searchControl; - })); - #endregion } return true; })); @@ -713,6 +670,13 @@ namespace Lskj.PubBillManagement this.xtc_main_container.TabPages.Clear(); Dictionary dataCaches = SysModel != null ? SysModel.DataCaches : null; + if (dataCaches != null && + dataCaches.GetTask(tb_buttom, "DynamicModel") != null && + dataCaches.GetTask>(tb_buttom, "Details") != null) + { + // 该方法会预创建附加页控件,必须在 UI 线程执行。 + tb_buttom.GetDataCaches(dataCaches); + } if (!dataCaches.GetValue(this, "Details", out List attachModels)) { attachModels = GetAttachTabs(); @@ -790,7 +754,7 @@ namespace Lskj.PubBillManagement treeView.Dock = DockStyle.Fill; treeView.TreeNodeKeyField = model.SourceKeyField; treeView.TreeNodeTextField = model.SourceResult; - if (!dataCaches.GetValue(treeView, "BindTreeTable", out DataTable bindTreeTable)) + if (!dataCaches.GetValue(billModuleModel, "BindTreeTable", out DataTable bindTreeTable)) { bindTreeTable = BaseImpl.GetDataTableResult(model.SourceSql); } @@ -814,15 +778,18 @@ namespace Lskj.PubBillManagement gridControl.BorderStyle = System.Windows.Forms.BorderStyle.None; gridControl.Model = this.SysModel; - if (!dataCaches.GetValue(gridControl, "SourceColumns", out DataTable dtSourceColumns)) + AttachCachedTask(dataCaches, billModuleModel, + "SourceCustomColumnByDatabase", gridControl, + "CustomColumnByDatabase"); + if (!dataCaches.GetValue(billModuleModel, "SourceColumns", out DataTable dtSourceColumns)) { dtSourceColumns = BillImpl.GetSourceColumns(model.Id); } - if (!dataCaches.GetValue(gridControl, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); } - if (!dataCaches.GetValue(gridControl, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); } @@ -855,19 +822,22 @@ namespace Lskj.PubBillManagement gridControl.Dock = DockStyle.Fill; gridControl.ExportPermission = this.BillModel.ExportPermission; + AttachCachedTask(dataCaches, billModuleModel, + "SourceCustomColumnByDatabase", gridControl, + "CustomColumnByDatabase"); if (model.LoadFilter) { gridControl.GridView.OptionsView.ShowAutoFilterRow = true; } - if (!dataCaches.GetValue(gridControl, "SourceColumns", out DataTable dtSourceColumns)) + if (!dataCaches.GetValue(billModuleModel, "SourceColumns", out DataTable dtSourceColumns)) { dtSourceColumns = BillImpl.GetSourceColumns(model.Id); } - if (!dataCaches.GetValue(gridControl, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey); } - if (!dataCaches.GetValue(gridControl, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey); } @@ -979,12 +949,15 @@ namespace Lskj.PubBillManagement gridDetail = sourceDetailControl != null ? (TreeGridControlEx)sourceDetailControl : new TreeGridControlEx(); gridDetail.Model = this.SysModel; gridDetail.Dock = DockStyle.Fill; + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailCustomColumnByDatabase", gridDetail, + "CustomColumnByDatabase"); gridDetail.SetReadOnlyColumns(detailColumns == null || detailColumns.Length == 0 ? new DataTable() : detailColumns.CopyToDataTable(), GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); - if (!dataCaches.GetValue(gridDetail, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); } - if (!dataCaches.GetValue(gridDetail, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); } @@ -1012,17 +985,20 @@ namespace Lskj.PubBillManagement gridDetail = sourceDetailControl != null ? (GridControlEx)sourceDetailControl : new GridControlEx(); gridDetail.Model = this.SysModel; gridDetail.Dock = DockStyle.Fill; + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailCustomColumnByDatabase", gridDetail, + "CustomColumnByDatabase"); gridDetail.SetReadOnlyColumns(detailColumns == null || detailColumns.Length == 0 ? new DataTable() : detailColumns.CopyToDataTable(), GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey); if (model.DetailedLoadFilter) { gridDetail.GridView.OptionsView.ShowAutoFilterRow = true; } - if (!dataCaches.GetValue(gridDetail, "BaseGridRowColors", out DataTable dtBaseGridRowColors)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRowColors", out DataTable dtBaseGridRowColors)) { dtBaseGridRowColors = BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey); } - if (!dataCaches.GetValue(gridDetail, "BaseGridRightMenus", out DataTable dtBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailBaseGridRightMenus", out DataTable dtBaseGridRightMenus)) { dtBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey); } @@ -1036,13 +1012,16 @@ namespace Lskj.PubBillManagement gridDetail_Details.Model = this.SysModel; gridDetail_Details.Dock = DockStyle.Fill; //创建只读列 - if (!dataCaches.GetValue(gridDetail_Details, "Detail_Details", out DataTable dataTable)) + if (!dataCaches.GetValue(billModuleModel, "DetailDetails", out DataTable dataTable)) { dataTable = BaseModuleImpl.getDetail_Details(model.FormKey); } + AttachCachedTask(dataCaches, billModuleModel, + "SourceDetailDetailsCustomColumnByDatabase", + gridDetail_Details, "CustomColumnByDatabase"); gridDetail_Details.SetReadOnlyColumns(dataTable); //设置右键 - if (!dataCaches.GetValue(gridDetail_Details, "BaseGridRightMenus", out DataTable dttBaseGridRightMenus)) + if (!dataCaches.GetValue(billModuleModel, "SourceDetailDetailsBaseGridRightMenus", out DataTable dttBaseGridRightMenus)) { dttBaseGridRightMenus = BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey); } @@ -1073,6 +1052,7 @@ namespace Lskj.PubBillManagement splitContainerControl.Parent = tabDetail; unionModel.GridDetailDetailControlObj = gridDetail_Details; + billModuleModel.SourceDetailDetailControl = gridDetail_Details; } else { @@ -1103,6 +1083,11 @@ namespace Lskj.PubBillManagement #endregion + billModuleModel.SourceControl = + treeView != null ? (object)treeView : gridControl; + billModuleModel.SourceDetailControl = gridDetail; + BillModuleModelDic[sourceModelRow] = billModuleModel; + #region 加载来源条件 if (model.SourceType == 1 && (controls == null || controls.Rows.Count == 0)) { @@ -1123,9 +1108,21 @@ namespace Lskj.PubBillManagement // 创建自定义条件 string searchSql = model.SourceType == 1 ? Regex.Replace(model.DetailSql, "{speciesno}", "", RegexOptions.IgnoreCase) : model.SourceSql; PanelControl searchPanel = new PanelControl(); - if (!dataCaches.GetValue(sourceModelRow, "SearchControl", out MyControl searchControl)) + MyControl searchControl = + new MyControl(searchSql, + gridControl == null ? gridDetail : gridControl, + treeView) { - searchControl = new MyControl(searchSql, gridControl == null ? gridDetail : gridControl, treeView); + Model = this.SysModel, + OtherParams = this.SysModel.OtherParams() + }; + if (dataCaches != null) + { + dataCaches.AddTask(searchControl, "DynamicModel", + new Task(() => this.SysModel)); + dataCaches.AddTask(searchControl, "ControlsTable", + new Task(() => controls)); + searchControl.GetSearchDataCaches(dataCaches); } searchControl.OnSearchBeforeCallBack += new SearchEventHandler(OnSearchBefore); searchControl.OnSearchAfterCallBack += new EventHandler(OnSearchAfterd); @@ -2471,4 +2468,4 @@ namespace Lskj.PubBillManagement } -} \ No newline at end of file +} diff --git a/插件库/Lskj.PubBillSpecial/BillModule.cs b/插件库/Lskj.PubBillSpecial/BillModule.cs index 0bcafe1..2832799 100644 --- a/插件库/Lskj.PubBillSpecial/BillModule.cs +++ b/插件库/Lskj.PubBillSpecial/BillModule.cs @@ -431,15 +431,8 @@ namespace Lskj.PubBillSpecial //if (billModel.CenterMain) dataTable = this.SetControlMargins(dataTable); return dataTable; })); - Task controlObjTask = cachesDic.AddTask(this, "ControlObj", new Task(() => - { - MyControl myControl = new MyControl() { Model = dynamicModel }; - myControl.OtherParams = dynamicModel.OtherParams(); - cachesDic.AddTask(myControl, "DynamicModel", dynamicModelTask); - cachesDic.AddTask(myControl, "ControlsTable", controlLocationTask); - myControl.GetControlDataCaches(cachesDic); - return myControl;//主表控件 - })); + // MyControl 持有 WinForms Timer。后台阶段只加载控件配置, + // 实际 MyControl 及编辑控件由 InitializeBillInfo 在 UI 线程创建。 Task addGroupDataTask = cachesDic.AddTask(this, "AddGroupData", new Task(() => { return BaseModuleImpl.GetAddGroupData(billModel.FormKey);//获取主信息分组数据 @@ -940,6 +933,15 @@ namespace Lskj.PubBillSpecial if (!dataCaches.GetValue(this, "ControlObj", out ControlObj)) { this.ControlObj = new MyControl() { Model = SysModel };//主表控件 + this.ControlObj.OtherParams = this.SysModel.OtherParams(); + if (dataCaches != null) + { + dataCaches.AddTask(this.ControlObj, "DynamicModel", + new Task(() => this.SysModel)); + dataCaches.AddTask(this.ControlObj, "ControlsTable", + new Task(() => controls)); + this.ControlObj.GetControlDataCaches(dataCaches); + } } @@ -6857,4 +6859,4 @@ namespace Lskj.PubBillSpecial } } } -} \ No newline at end of file +}