fix(legacy): keep bill cache control creation on UI thread

This commit is contained in:
2026-08-30 21:42:56 +08:00
parent 769aa52241
commit 0058939a8a
4 changed files with 322 additions and 277 deletions
+200 -154
View File
@@ -219,6 +219,12 @@ namespace Lskj.PubBill
/// </summary>
public Dictionary<DataRow, BillModuleModel> BillModuleModelDic = new Dictionary<DataRow, BillModuleModel>();
/// <summary>
/// 当前单据在 UI 线程创建的来源明细页。部分非首来源页不会立即加入
/// TabControl,模块永久关闭时需要按所属范围释放这些脱离父级的页面。
/// </summary>
private readonly HashSet<XtraTabPage> _ownedSourceDetailPages =
new HashSet<XtraTabPage>();
/// <summary>
/// 主表动态生成的日期列
/// </summary>
public List<GridColumn> DateColumnList = new List<GridColumn>();
@@ -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<System.Windows.Forms.Control> target,
object sourceControl)
@@ -445,6 +495,24 @@ namespace Lskj.PubBill
target.Add(control);
}
private static void AttachCachedTask<T>(
Dictionary<object, Hashtable> cachesDic,
object cacheOwner,
string cacheKey,
object control,
string controlKey)
{
if (cachesDic == null || cacheOwner == null || control == null ||
cachesDic.GetTask<T>(control, controlKey) != null)
{
return;
}
Task<T> task = cachesDic.GetTask<T>(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<int, DataRow> rows in ToWithdrawRows)
if (rows != null)
@@ -952,16 +1021,8 @@ namespace Lskj.PubBill
}
return controls;
}));
Task<MyControl> controlObjTask = cachesDic.AddTask(this, "ControlObj", new Task<MyControl>(() =>
{
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<DataTable> addGroupDataTask = cachesDic.AddTask(this, "AddGroupData", new Task<DataTable>(() =>
{
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<bool> initSourcesTask = cachesDic.AddTask(this, "InitSourcesTask", new Task<bool>(() =>
{
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<DataTable> bindTreeTableTask = cachesDic.AddTask(treeView, "BindTreeTable", new Task<DataTable>(() =>
cachesDic.AddTask(billModuleModel, "BindTreeTable", new Task<DataTable>(() =>
{
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<DataTable> sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task<DataTable>(() =>
{
return BillImpl.GetSourceColumns(model.Id);
}));
Task<DataTable> sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey);
}));
Task<DataTable> sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCE_" + model.FormKey);
}));
}
else
{
// 来源为表格类型
gridControl = new GridControlEx();
billModuleModel.SourceControl = gridControl;
Task<DataTable> sourceColumnsTask = cachesDic.AddTask(gridControl, "SourceColumns", new Task<DataTable>(() =>
if (model.SourceType == 5)
model.ChangeSourceType(2);//单据来源显示条数
cachesDic.AddTask(billModuleModel, "SourceColumns", new Task<DataTable>(() =>
{
return BillImpl.GetSourceColumns(model.Id);
}));
//创建表格列
cachesDic.AddTask(gridControl, "DynamicModel", dynamicModelTask);
gridControl.GetDataCaches(cachesDic, GridCustomColumnStruct.BillSourceGridView + model.FormKey);
Task<DataTable> sourceGridRowColorsTask = cachesDic.AddTask(gridControl, "BaseGridRowColors", new Task<DataTable>(() =>
cachesDic.AddTask(billModuleModel, "SourceCustomColumnByDatabase", new Task<DataTable>(() =>
{
return GridExtend.GetCustomColumnByDatabase(
GridCustomColumnStruct.BillSourceGridView + model.FormKey);
}));
cachesDic.AddTask(billModuleModel, "SourceBaseGridRowColors", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRowColors("BILLSOURCE_" + model.FormKey);
}));
Task<DataTable> sourceGridRightMenusTask = cachesDic.AddTask(gridControl, "BaseGridRightMenus", new Task<DataTable>(() =>
cachesDic.AddTask(billModuleModel, "SourceBaseGridRightMenus", new Task<DataTable>(() =>
{
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<DataTable>(() =>
{
return GridExtend.GetCustomColumnByDatabase(
GridCustomColumnStruct.BillSourceDetailGridView + model.FormKey);
}));
cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRowColors", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey);
}));
cachesDic.AddTask(billModuleModel, "SourceDetailBaseGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey);
}));
if (!string.IsNullOrEmpty(model.SourceDetailsDetailsSql))
{
cachesDic.AddTask(billModuleModel, "DetailDetails", new Task<DataTable>(() =>
{
return BaseModuleImpl.getDetail_Details(model.FormKey);
}));
cachesDic.AddTask(billModuleModel, "SourceDetailDetailsCustomColumnByDatabase", new Task<DataTable>(() =>
{
return GridExtend.GetCustomColumnByDatabase(string.Empty);
}));
cachesDic.AddTask(billModuleModel, "SourceDetailDetailsBaseGridRightMenus", new Task<DataTable>(() =>
{
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<DataTable> detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey);
}));
Task<DataTable> detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task<DataTable>(() =>
{
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<DataTable> detailGridRowColorsTask = cachesDic.AddTask(gridDetail, "BaseGridRowColors", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRowColors("SOURCEDETAIL_" + model.FormKey);
}));
Task<DataTable> detailGridRightMenusTask = cachesDic.AddTask(gridDetail, "BaseGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDT_" + model.FormKey);
}));
//明细的明细(明细分成左右2个)
if (!string.IsNullOrEmpty(model.SourceDetailsDetailsSql))
{
GridControlEx gridDetail_Details = new GridControlEx();
billModuleModel.SourceDetailDetailControl = gridDetail_Details;
//创建只读列
Task<DataTable> detailDetailsTask = cachesDic.AddTask(gridDetail_Details, "DetailDetails", new Task<DataTable>(() =>
{
return BaseModuleImpl.getDetail_Details(model.FormKey);
}));
//创建表格列
cachesDic.AddTask(gridDetail_Details, "DynamicModel", dynamicModelTask);
gridDetail_Details.GetDataCaches(cachesDic);
Task<DataTable> detailDetailsGridRightMenusTask = cachesDic.AddTask(gridDetail_Details, "BaseGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus("BILLSOURCEDTX_" + model.FormKey);
}));
}
}
}
#endregion
BillModuleModelDic.Add(sourceModelRow, billModuleModel);
#region
Task<MyControl> searchControlTask = cachesDic.AddTask(sourceModelRow, "SearchControl", new Task<MyControl>(() =>
{
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<DynamicModel>(() => this.SysModel));
dataCaches.AddTask(this.ControlObj, "ControlsTable",
new Task<DataTable>(() => 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<object, Hashtable> dataCaches = SysModel != null ? SysModel.DataCaches : null;
if (dataCaches != null &&
dataCaches.GetTask<DynamicModel>(tb_buttom, "DynamicModel") != null &&
dataCaches.GetTask<List<GridDetailModel>>(tb_buttom, "Details") != null)
{
// 该方法会预创建附加页控件,必须在 UI 线程执行;其内部查询
// 任务仍由原有 TaskSchedulerUtil 并行调度。
tb_buttom.GetDataCaches(dataCaches);
}
if (!dataCaches.GetValue(this, "Details", out List<GridDetailModel> 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<DataTable>(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<DataTable>(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<DataTable>(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<DataTable>(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<DataTable>(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<DataTable>(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<DynamicModel>(() => this.SysModel));
dataCaches.AddTask(searchControl, "ControlsTable",
new Task<DataTable>(() => 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;
}