feat: 优化初始化缓存及控件功能

This commit is contained in:
cyf
2026-08-14 20:33:43 +08:00
parent 222ae3c08a
commit f665688d0b
27 changed files with 505 additions and 106 deletions
@@ -71,24 +71,24 @@ namespace NewMyFormDesigner
}
//DialogResult dr = MessageBox.Show("是否为达梦数据库?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
//if (dr == System.Windows.Forms.DialogResult.Yes)
//{
// if (!string.IsNullOrWhiteSpace(ServerName) && !string.IsNullOrWhiteSpace(DatabaseName) && !string.IsNullOrWhiteSpace(AccountNumber))
// {
// string connect = "Nzg5REZBQ0IzMjYzQkQzRTZFRTExNjY5MThCNjUwQTVFRUQyMDMxQzI5REIwODY5REIwMkVCQzQ4MTMzRDhDNEU1N0JFREI0MDM3MTQ1MDZGQzdGOEQxQTE4MkQ2QzgyNEE4RkMzRDQzQUM4MzgyOEQ2REZERTIzQzBDMjJGQUE=";
// string hostname = Environment.MachineName;
// if (!string.IsNullOrWhiteSpace(Password))
// {
// LinkString = string.Format("Server={0}; schema={1}; UserId={2}; PWD={3};host={4}", ServerName, DatabaseName, AccountNumber, Password, hostname);
// }
// else
// {
// LinkString = string.Format(Lskj.Util.AESUtil.Decrypt(connect), ServerName, DatabaseName, AccountNumber, hostname);
// }
// connectionType = ConnectionType.DmServer;
// }
//}
DialogResult dr = MessageBox.Show("是否为达梦数据库?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr == System.Windows.Forms.DialogResult.Yes)
{
if (!string.IsNullOrWhiteSpace(ServerName) && !string.IsNullOrWhiteSpace(DatabaseName) && !string.IsNullOrWhiteSpace(AccountNumber))
{
string connect = "Nzg5REZBQ0IzMjYzQkQzRTZFRTExNjY5MThCNjUwQTVFRUQyMDMxQzI5REIwODY5REIwMkVCQzQ4MTMzRDhDNEU1N0JFREI0MDM3MTQ1MDZGQzdGOEQxQTE4MkQ2QzgyNEE4RkMzRDQzQUM4MzgyOEQ2REZERTIzQzBDMjJGQUE=";
string hostname = Environment.MachineName;
if (!string.IsNullOrWhiteSpace(Password))
{
LinkString = string.Format("Server={0}; schema={1}; UserId={2}; PWD={3};host={4}", ServerName, DatabaseName, AccountNumber, Password, hostname);
}
else
{
LinkString = string.Format(Lskj.Util.AESUtil.Decrypt(connect), ServerName, DatabaseName, AccountNumber, hostname);
}
connectionType = ConnectionType.DmServer;
}
}
//MessageBox.Show(LinkString);
+2 -2
View File
@@ -32,10 +32,10 @@ namespace NewMyFormDesigner
//myFormDesigner.ServerName = "110.185.161.104:5236";
//myFormDesigner.ServerName = "222.211.229.79:5238";
//myFormDesigner.DatabaseName = "LSERP_JTCS";
//myFormDesigner.AccountNumber = "lserpAdmin";
//myFormDesigner.Password = "DWlserp1101";//XDerp20210411%
//myFormDesigner.Password = "Lserp110";//XDerp20210411%
//MessageBox.Show(args.Length + "");
//MessageBox.Show("1:"+args[0]);
+33 -3
View File
@@ -926,7 +926,15 @@ namespace Lskj.Business.Impl
{
string field = string.Empty;
DataTable dataTable = GetTableColumns("p_systembillsourcecond");
DataTable dataTable;
try
{
dataTable = InitialParamCache.GetTableColumns("p_systembillsourcecond", delegate { return GetTableColumns("p_systembillsourcecond"); });
}
catch (Exception)
{
dataTable = GetTableColumns("p_systembillsourcecond");
}
if (dataTable.Columns.Contains("FontSize"))
{
@@ -1015,6 +1023,7 @@ namespace Lskj.Business.Impl
/// <exception cref="System.NotImplementedException"></exception>
public static DataTable GetSchemesList(int moduleId)
{
if (moduleId <= 0) return new DataTable();
try
{
string sqlValue = "select * from P_SystemReportProjectTab where ProjectMode=1 and operatorId=@userid and ModuleId=@moduleId";
@@ -1141,7 +1150,16 @@ namespace Lskj.Business.Impl
switch (type)
{
case ModuleType.MrpClickBtn:
if (BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int"))
bool isMrpClickBtnExists;
try
{
isMrpClickBtnExists = InitialParamCache.GetColumnExists("P_systempopupmenu", "isMrpClickBtn", "int", delegate { return BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int"); });
}
catch (Exception)
{
isMrpClickBtnExists = BaseImpl.HasExistsColumn("P_systempopupmenu", "isMrpClickBtn", "int");
}
if (isMrpClickBtnExists)
{
where = " and isnull(isMrpClickBtn,0)=1 and visible1=0 ";
}
@@ -1563,7 +1581,19 @@ namespace Lskj.Business.Impl
//保存条件表
public static DataTable GetClientCond(string MenuCode)
{
if (BaseImpl.HasExistsTable("P_SystemClientCondTab"))
const string tableName = "P_SystemClientCondTab";
bool tableExists;
try
{
tableExists = InitialParamCache.GetTableExists(tableName, delegate { return BaseImpl.HasExistsTable(tableName); });
}
catch (Exception)
{
// 缓存未能正常读取或记录时,重新查询,避免影响原有功能。
tableExists = BaseImpl.HasExistsTable(tableName);
}
if (tableExists)
{
string sqlValue = string.Format(@"select * from P_SystemClientCondTab where tab='{0}' and disableflag=0 order by orderid ", MenuCode);
return GetDataTableResult(sqlValue);
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Data;
namespace Lskj.Business.Impl
{
/// <summary>
/// 单次模块初始化期间复用的参数缓存。
/// </summary>
public static class InitialParamCache
{
private static readonly object SyncRoot = new object();
private static readonly Dictionary<string, bool> TableExistsCache =
new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, bool> ColumnExistsCache =
new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, DataTable> TableColumnsCache =
new Dictionary<string, DataTable>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// 获取表是否存在。没有缓存时执行查询,并记录查询结果。
/// </summary>
public static bool GetTableExists(string tableName, Func<bool> query)
{
if (string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("表名不能为空。", "tableName");
}
if (query == null)
{
throw new ArgumentNullException("query");
}
lock (SyncRoot)
{
bool tableExists;
if (TableExistsCache.TryGetValue(tableName, out tableExists))
{
return tableExists;
}
tableExists = query();
TableExistsCache[tableName] = tableExists;
return tableExists;
}
}
/// <summary>
/// 获取字段是否存在。没有缓存时执行查询,并记录查询结果。
/// </summary>
public static bool GetColumnExists(string tableName, string columnName, string columnType, Func<bool> query)
{
if (string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("表名不能为空。", "tableName");
}
if (string.IsNullOrWhiteSpace(columnName))
{
throw new ArgumentException("字段名不能为空。", "columnName");
}
if (query == null)
{
throw new ArgumentNullException("query");
}
string cacheKey = tableName + "|" + columnName + "|" + (columnType ?? string.Empty);
lock (SyncRoot)
{
bool columnExists;
if (ColumnExistsCache.TryGetValue(cacheKey, out columnExists))
{
return columnExists;
}
columnExists = query();
ColumnExistsCache[cacheKey] = columnExists;
return columnExists;
}
}
/// <summary>
/// 获取表结构。没有缓存时执行查询,并缓存不包含数据的结构模板。
/// </summary>
public static DataTable GetTableColumns(string tableName, Func<DataTable> query)
{
if (string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("表名不能为空。", "tableName");
}
if (query == null)
{
throw new ArgumentNullException("query");
}
lock (SyncRoot)
{
DataTable tableColumns;
if (!TableColumnsCache.TryGetValue(tableName, out tableColumns))
{
DataTable queryResult = query();
if (queryResult == null)
{
throw new InvalidOperationException("获取表结构失败。" + tableName);
}
tableColumns = queryResult.Clone();
TableColumnsCache[tableName] = tableColumns;
}
return tableColumns.Clone();
}
}
/// <summary>
/// 清空上一次模块初始化记录的参数。
/// </summary>
public static void Clear()
{
lock (SyncRoot)
{
TableExistsCache.Clear();
ColumnExistsCache.Clear();
TableColumnsCache.Clear();
}
}
}
}
@@ -87,6 +87,7 @@
<Compile Include="Impl\BillImpl.cs" />
<Compile Include="Impl\ConditionalCaching.cs" />
<Compile Include="Impl\ErrorMessage.cs" />
<Compile Include="Impl\InitialParamCache.cs" />
<Compile Include="Impl\LanguageTranslation.cs" />
<Compile Include="Impl\MainImpl.cs" />
<Compile Include="Impl\BillAuditImpl.cs" />
@@ -1612,7 +1612,6 @@ namespace Lskj.Control
{
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
Popup.BottomPanelObj.Visible = true;
Popup.GridControlObj.DataSourceTable().Clear();
}
_queryWorker.Queue(new PopupQueryRequest
+6 -2
View File
@@ -654,13 +654,14 @@ namespace Lskj.Control
if (parametersArray.Length > i)
{
string commandParameter = parametersArray[i];
//string field = commandParameter.Replace("@", "").Replace("{", "").Replace("}", "");
string field = commandParameter.Replace("@", "").Replace("{", "").Replace("}", "");
//string value = focusedRow.Table.Columns.Contains(field) ? focusedRow[field] + "" : commandParameter.Replace("@", "");
//value = SearchObj.ReplaceControlValue(value);
//value = TopControlObj.ReplaceControlValue(value);
//value = ReplaceControlValue(value, MainControlPanel);
//value = value.Replace("@", "").Replace("{", "").Replace("}", "");
//sqlParameter.Value = value;
sqlParameter.Value = field;
}
}
SqlParameter returnValue = new SqlParameter("@return", SqlDbType.Int, 4);
@@ -670,16 +671,19 @@ namespace Lskj.Control
if (!(returnValue.Value + "").Equals("1"))
{
SqlParameter outSqlParameter = sqlParameters.Cast<SqlParameter>().Where(n => n.Direction == ParameterDirection.Output).FirstOrDefault();
string msg = "导入后执行sql失败";
if (outSqlParameter != null)
{
string outMessage = outSqlParameter.Value + "";
if (!string.IsNullOrEmpty(outMessage))
{
MessageUtil.Show("导入后执行sql失败:" + outSqlParameter.Value + "");
msg="导入后执行sql失败:" + outSqlParameter.Value + "";
}
}
MessageUtil.Show(msg);
string deleteSql = string.Format("delete from {0} where {1}='1'", this._tableName, this._importFlag);
SqlHelper.ExecuteNonQuery(deleteSql);
return false;
}
}
else
+4 -1
View File
@@ -1157,7 +1157,10 @@ namespace Lskj.Control
if (groupDataTable.Columns.Count > 0)
{
DataTable orderTable = groupDataTable.Clone();
groupDataTable.Select().OrderBy(n => n[groupDataTable.Columns[0]]).CopyToDataTable(orderTable, LoadOption.PreserveChanges);
// DataTable中的数据库空值是DBNull,不能直接和String等实际类型比较。
// 仅将DBNull作为null参与排序,非空数据仍按字段原始类型排序。
DataColumn orderColumn = groupDataTable.Columns[0];
groupDataTable.Select().OrderBy(n => n.IsNull(orderColumn) ? null : n[orderColumn]).CopyToDataTable(orderTable, LoadOption.PreserveChanges);
InitShowDataGridColumns(orderTable);
try
{
+16 -1
View File
@@ -94,6 +94,11 @@ namespace Lskj.Control
/// 父容器表格
/// </summary>
public GridControlEx ParentGridEx;
/// <summary>
/// 父容器表格条件
/// </summary>
public MyControl SearchObj;
/// <summary>
/// 源表格
@@ -391,6 +396,7 @@ namespace Lskj.Control
//提交到数据库
try
{
WaitForm.ShowForm();
string sql = "select * from " + _tableName + " where 1<>1";
//SqlDataAdapter dat = BaseImpl.GetAdapterResult(sql);
//SqlCommandBuilder scb = new SqlCommandBuilder(dat);
@@ -678,6 +684,10 @@ namespace Lskj.Control
string errorMsg = string.Format("{0}\r\n第{1}行,第{2}列\r\n列名:{3}", mesage, rowNum, colNum, colName);
XtraMessageBox.Show("数据提交错误:\n" + errorMsg + "\r\n", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
WaitForm.HideForm();
}
}
/// <summary>
/// 数字转换时间格式
@@ -954,7 +964,12 @@ namespace Lskj.Control
DataRow SelectTheLine = this.ParentGridEx.GetViewFocusedDataRow();
fieldValue = ReplaceHelper.ReplaceRowParam(SelectTheLine, fieldValue);
}
fieldValue= BaseImpl.GetDefaultValue(fieldValue);
if (this.SearchObj != null)
{
fieldValue = this.SearchObj.ReplaceParentControlValue(fieldValue);
}
fieldValue = BaseImpl.GetDefaultValue(fieldValue);
if (!string.IsNullOrEmpty(fieldValue))
{
rowItem[col.FieldName] = fieldValue;
+20
View File
@@ -73,6 +73,10 @@ namespace Lskj.Control
/// </summary>
private bool isFirstVisableCol = true;
/// <summary>
/// 表格自定义字体
/// </summary>
private System.Drawing.Text.PrivateFontCollection customFont = new System.Drawing.Text.PrivateFontCollection();
/// <summary>
/// The _grid enum object
/// </summary>
private HeaderSiftEnum _columnEnumObj;
@@ -5532,6 +5536,9 @@ namespace Lskj.Control
/// <param name="e">事件参数。</param>
private void OnGridControlExDisposed(object sender, EventArgs e)
{
if (_gridResourcesDisposed) return;
_gridResourcesDisposed = true;
foreach (FrmModelLookUp2 modelLookUp in selectReturnModelLookUpCache.Values.Distinct())
{
if (modelLookUp != null && !modelLookUp.IsDisposed)
@@ -5541,6 +5548,19 @@ namespace Lskj.Control
}
selectReturnModelLookUpCache.Clear();
selectReturnDisplaySourceCache.Clear();
if (_mainGridToolTipController != null)
{
_mainGridToolTipController.BeforeShow -= MainGvTool_BeforeShow;
_mainGridToolTipController.Dispose();
_mainGridToolTipController = null;
}
if (customFont != null)
{
customFont.Dispose();
customFont = null;
}
}
/// <summary>
+42 -1
View File
@@ -24,8 +24,9 @@ namespace Lskj.Control.Model
/// <summary>
/// 表格拖拽到树结构
/// </summary>
public class GridDragTree
public class GridDragTree : IDisposable
{
private bool _disposed;
/// <summary>
/// 拖动位置
/// </summary>
@@ -59,6 +60,46 @@ namespace Lskj.Control.Model
this._treeView.AllowDrop = true;
this._treeView.DragOver += new DragEventHandler(treeView_DragOver);
this._treeView.DragDrop += new DragEventHandler(treeView_DragDrop);
if (this._gridView.GridControl != null)
{
this._gridView.GridControl.Disposed += OnOwnerDisposed;
}
this._treeView.Disposed += OnOwnerDisposed;
}
private void OnOwnerDisposed(object sender, EventArgs e)
{
Dispose();
}
/// <summary>
/// 模块关闭时解除源表格和目标树的拖拽事件。
/// </summary>
public void Dispose()
{
if (_disposed) return;
_disposed = true;
if (_gridView != null)
{
_gridView.MouseDown -= gridView_MouseDown;
_gridView.MouseMove -= gridView_MouseMove;
if (_gridView.GridControl != null)
{
_gridView.GridControl.Disposed -= OnOwnerDisposed;
}
}
if (_treeView != null)
{
_treeView.DragOver -= treeView_DragOver;
_treeView.DragDrop -= treeView_DragDrop;
_treeView.Disposed -= OnOwnerDisposed;
}
OnDragComplete = null;
_hitInfo = null;
_gridView = null;
_treeView = null;
}
+1 -1
View File
@@ -950,7 +950,7 @@ namespace Lskj.Control.Model
{
try
{
if (!BaseImpl.HasExistsColumn(ResourceKeys.SettingTableName, ""))
if (!BaseImpl.HasExistsColumn(ResourceKeys.SettingTableName, "IfFixColumn"))
{
BaseImpl.ExecSqlValue("alter table " + ResourceKeys.SettingTableName + " add IfFixColumn bit");
}
@@ -114,6 +114,7 @@ namespace Lskj.Control.Model.MenuStrip
{
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
if (conditionRows.Length == 0) continue;
foreach (DataRow selectRow in conditionRows)
{
@@ -137,6 +137,7 @@ namespace Lskj.Control.Model
{
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
if (conditionRows.Length == 0) continue;
foreach (DataRow selectRow in conditionRows)
{
@@ -147,6 +147,7 @@ namespace Lskj.Control.Model.MenuStrip
{
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
if (conditionRows.Length == 0) continue;
foreach (DataRow selectRow in conditionRows)
{
+27 -5
View File
@@ -133,6 +133,10 @@ namespace Lskj.Control.Model
public DataRow CurrentData;
public ModuleModel SystemModel;
/// <summary>
/// 外部已查询的MRP操作按钮数据;为空时保持原查询逻辑。
/// </summary>
public DataTable MrpClickMenus;
/// <summary>
/// 下拉框、搜索框控件对象
/// </summary>
public List<ControlModel> mControlList = new List<ControlModel>();
@@ -899,10 +903,13 @@ namespace Lskj.Control.Model
return controlModel;
}));
}
if (MrpClickMenus == null)
{
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}));
}
return true;
}));
}
@@ -1042,7 +1049,17 @@ namespace Lskj.Control.Model
}
if (dynamicModel != null && !string.IsNullOrEmpty(dynamicModel.ModuleCode))
{
if (!dataCaches.GetValue(parent, "SysModel", out ModuleModel moduleModel))
ModuleModel moduleModel = null;
if (SystemModel != null && string.Equals(SystemModel.ModeCode, dynamicModel.ModuleCode, StringComparison.OrdinalIgnoreCase))
{
moduleModel = SystemModel;
}
if (moduleModel == null && dataCaches.GetValue(parent, "SysModel", out ModuleModel cacheModuleModel) &&
cacheModuleModel != null && string.Equals(cacheModuleModel.ModeCode, dynamicModel.ModuleCode, StringComparison.OrdinalIgnoreCase))
{
moduleModel = cacheModuleModel;
}
if (moduleModel == null)
{
moduleModel = new ModuleModel(MainImpl.GetSystemdllTab(dynamicModel.ModuleCode));
}
@@ -1060,13 +1077,14 @@ namespace Lskj.Control.Model
btnCondSearch.Click += new EventHandler(OnBtnCondSearchClick);
}
}
DataTable rightDt = null;
if (dynamicModel != null)
DataTable rightDt = MrpClickMenus;
if (rightDt == null && dynamicModel != null)
{
if (!dataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
{
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}
MrpClickMenus = rightDt;
}
if (rightDt != null && rightDt.Rows.Count > 0)
{
@@ -1220,13 +1238,14 @@ namespace Lskj.Control.Model
_popupMenu.Name = "pm_search";
CreateSearchScheme();
}
DataTable rightDt = null;
if (dynamicModel != null)
DataTable rightDt = MrpClickMenus;
if (rightDt == null && dynamicModel != null)
{
if (!dynamicModel.DataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
{
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}
MrpClickMenus = rightDt;
}
if (rightDt != null && rightDt.Rows.Count > 0)
{
@@ -1295,10 +1314,13 @@ namespace Lskj.Control.Model
return controlModel;
}));
}
if (MrpClickMenus == null)
{
Task<DataTable> rightDtGridRightMenusTask = cachesDic.AddTask(this, "RightDtGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}));
}
return true;
}));
}
+32 -8
View File
@@ -62,6 +62,9 @@ namespace Lskj.Control
/// 左侧表格查询条件
/// </summary>
private MyControl _leftGridSearchObj;
private GridDragTree _gridDragTree;
private GridDragGrid _gridDragGrid;
private BandedGridDragGrid _bandedGridDragGrid;
public bool IsExcel { get { return Model is DynamicExcelModel; } }
/// <summary>
@@ -150,6 +153,7 @@ namespace Lskj.Control
public ModuleEx()
{
InitializeComponent();
this.Disposed += OnModuleExDisposed;
}
/// <summary>
@@ -249,9 +253,10 @@ namespace Lskj.Control
if (Model.HasOperPrivilege() && model.IsBaseModule)
{
// 有权限则允许拖拽
GridDragTree dragTree = new GridDragTree(this.ModuleGridObj.GridControlObj.GridView, this.treeLeft.TreeView);
dragTree.CanDragParentNode = true;
dragTree.OnDragComplete += new GridDragTreeCompleteEventHandler(OnDragTreeCompleted);
_gridDragTree?.Dispose();
_gridDragTree = new GridDragTree(this.ModuleGridObj.GridControlObj.GridView, this.treeLeft.TreeView);
_gridDragTree.CanDragParentNode = true;
_gridDragTree.OnDragComplete += new GridDragTreeCompleteEventHandler(OnDragTreeCompleted);
}
if (this.SysModel.TreeDoubleClick)
{
@@ -298,10 +303,11 @@ namespace Lskj.Control
if (Model.HasOperPrivilege() && model.IsBaseModule && !this.SysModel.IsTreeTable)
{
// 有权限则允许拖拽
GridDragGrid dragGrid = new GridDragGrid(this.ModuleGridObj.GridControlObj.GridView, this.gridLeft.GridView);
dragGrid.OnDragComplete += new GridFragGridCompleteEventHandler(OnDragGridCompleted);
_gridDragGrid?.Dispose();
_gridDragGrid = new GridDragGrid(this.ModuleGridObj.GridControlObj.GridView, this.gridLeft.GridView);
_gridDragGrid.OnDragComplete += new GridFragGridCompleteEventHandler(OnDragGridCompleted);
//配置了拖拽条件后,在点击时判断条件
dragGrid.DragConditions = this.SysModel.DragConditions;
_gridDragGrid.DragConditions = this.SysModel.DragConditions;
}
break;
@@ -374,8 +380,9 @@ namespace Lskj.Control
if (Model.HasOperPrivilege() && model.IsBaseModule && !this.SysModel.IsTreeTable && this.ModuleGridObj.GridControlObj.GridView is BandedGridView&&(this.SysModel.MenuType==2 || this.SysModel.MenuType==5))
{
// 有权限则允许拖拽
BandedGridDragGrid BandedDragGrid = new BandedGridDragGrid(this.ModuleGridObj.GridControlObj.GridView as BandedGridView, this.gridLeft.GridView);
BandedDragGrid.OnDragComplete += new BandedGridFragGridCompleteEventHandler(OnDragBandedGridCompleted);
_bandedGridDragGrid?.Dispose();
_bandedGridDragGrid = new BandedGridDragGrid(this.ModuleGridObj.GridControlObj.GridView as BandedGridView, this.gridLeft.GridView);
_bandedGridDragGrid.OnDragComplete += new BandedGridFragGridCompleteEventHandler(OnDragBandedGridCompleted);
}
}
@@ -1999,6 +2006,23 @@ namespace Lskj.Control
}
}
/// <summary>
/// 控件销毁后释放拖拽辅助对象;关闭被取消时不会触发,不影响模块继续使用。
/// </summary>
private void OnModuleExDisposed(object sender, EventArgs e)
{
this.Disposed -= OnModuleExDisposed;
_gridDragTree?.Dispose();
_gridDragTree = null;
_gridDragGrid?.Dispose();
_gridDragGrid = null;
_bandedGridDragGrid?.Dispose();
_bandedGridDragGrid = null;
}
/// <summary>
/// 初始化页签
@@ -231,6 +231,12 @@ namespace Lskj.Control
cachesDic.AddTask(ModuleGridObj, "DynamicModel", dynamicModelTask);
cachesDic.AddTask(ModuleGridObj, "SysModel", sysModelTask);
this.ModuleGridObj.GetDataCaches(cachesDic);
// 下方模块都使用当前主表的主键,共享主表已经创建的查询任务,避免每个明细重复查询。
Task<string> parentPrimaryKeyTask = cachesDic.GetTask<string>(ModuleGridObj, "BasePrimaryKey");
if (parentPrimaryKeyTask != null)
{
cachesDic.AddTask(tcButtom, "ParentPrimaryKey", parentPrimaryKeyTask);
}
if (!string.IsNullOrEmpty(sysModel.MainModuleCodeField) && this.ModuleGridObj.GridControlObj.GridView.Columns.ColumnByFieldName(sysModel.MainModuleCodeField) != null)
{
//InitializeDynamicPages();
+69 -33
View File
@@ -77,6 +77,10 @@ namespace Lskj.Control
/// </summary>
private bool _visibleMrpSearchPanel;
/// <summary>
/// 外部已查询的MRP操作按钮数据,供搜索区域复用。
/// </summary>
public DataTable MrpClickMenus;
/// <summary>
/// 底部操作按钮是否显示简短模式,默认为简短模式
/// </summary>
private bool _operShortMode = true;
@@ -518,6 +522,9 @@ namespace Lskj.Control
searchObj.Model = Model;
}
this.SearchObj = searchObj;
// 搜索区域复用当前模块配置,MyControl 内部会校验模块号,不一致时仍按原逻辑查询。
this.SearchObj.SystemModel = this.SysModel;
this.SearchObj.MrpClickMenus = this.MrpClickMenus;
if (this._leftGridField != null)
{
@@ -539,13 +546,6 @@ namespace Lskj.Control
if (fixedQuery)
{
//固定条件不显示,隐藏上方。(只显示表格)
if (SystemInfo.Instance.HideFixedConditions)
{
this.pl_top.Visible = false;
return;
}
this.pl_top_fix_search.Visible = true;
// 加载固定查询条件
@@ -558,7 +558,12 @@ namespace Lskj.Control
{
table = Business.Impl.LanguageTranslation.TranslationTableColumn(table, "fieldText");
}
//固定条件不显示,隐藏上方。(只显示表格)
if (SystemInfo.Instance.HideFixedConditions)
{
this.pl_top.Visible = false;
table = new DataTable();
}
// DataTable
this.cbField.DisplayMember = "fieldText";
@@ -3470,6 +3475,12 @@ namespace Lskj.Control
// 刷新数据
if (ImportResults)
{
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
{
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
string newResult = SqlHelper.ExecuteScalar(sql) + "";
}
if (ImportReturnName.Count > 0)
{
this.SearchObj.SearchGrid();
@@ -3478,11 +3489,7 @@ namespace Lskj.Control
{
this.SearchObj.SearchLastGrid();
}
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
{
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
string newResult = SqlHelper.ExecuteScalar(sql) + "";
}
}
//GridColumnCollection gridColumns = this.gcMain.GridView.Columns;
@@ -3517,11 +3524,20 @@ namespace Lskj.Control
FrmImport import = new FrmImport(this.SysModel.MenuTable, this.Model.ModuleCode, _parmaryKey, this.gcMain, this.SysModel.PrefixKey, leftField, leftValue, this.Model.FormText, this.SysModel.ConcatenatedPrefix);
import.ParentGridEx = this.ParentGridEx;
import.SearchObj = this.SearchObj;
import.ImportReturnName = ImportReturnName;
import.ImportReturnValue = ImportReturnValue;
DialogResult result = import.ShowDialog();
if (result == DialogResult.OK)
{
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
{
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
string newResult = SqlHelper.ExecuteScalar(sql) + "";
//if (!string.IsNullOrEmpty(newResult)) MessageUtil.Show(newResult);
}
// 刷新数据
if (ImportReturnName.Count > 0)
{
@@ -3532,14 +3548,6 @@ namespace Lskj.Control
this.SearchObj.SearchLastGrid();
}
if (!string.IsNullOrWhiteSpace(this.SysModel.afterimportSql))
{
string sql = this.SearchObj.ReplaceControlValue(this.SysModel.afterimportSql);
string newResult = SqlHelper.ExecuteScalar(sql) + "";
//if (!string.IsNullOrEmpty(newResult)) MessageUtil.Show(newResult);
}
}
}
@@ -3678,6 +3686,32 @@ namespace Lskj.Control
{
InitializeComponent();
this.OperShortMode = true;
this.Disposed += OnModuleGridExDisposed;
}
/// <summary>
/// 清理公共事件和全局右键引用,避免模块关闭后仍保留当前表格。
/// </summary>
private void OnModuleGridExDisposed(object sender, EventArgs e)
{
this.Disposed -= OnModuleGridExDisposed;
PrintUtil.OnAfterPrint -= OnReportPrintAfter;
if (SearchObj != null)
{
SearchObj.OnSearchBeforeCallBack -= OnSearchBeforeCallBack;
SearchObj.OnSearchAfterCallBack -= OnSearchAfterCallBack;
SearchObj.OnDataSourceBindCallBack -= OnMainSearchDataSourceBindCallBack;
if (ReferenceEquals(StaticControl.RightMenuMyControl, SearchObj))
{
StaticControl.RightMenuMyControl = null;
}
}
if (gcMain != null && ReferenceEquals(StaticControl.RightMenuGridView, gcMain.GridView))
{
StaticControl.RightMenuGridView = null;
}
}
/// <summary>
@@ -3789,13 +3823,10 @@ namespace Lskj.Control
}
if (this.SearchObj != null)
{
this.SearchObj.SystemModel = sysModel;
}
//if (this.SearchObj != null)
//{
// this.SearchObj.SystemModel = sysModel;
//}
//禁用条件
if (this.SysModel.ForbiddenCondition)
@@ -3962,15 +3993,22 @@ namespace Lskj.Control
{
return BaseModuleImpl.GetSchemesList(dynamicModel.ModuleId);//获取高级查询条件模版
}));
Task<DataTable> mrpClickMenusTask = cachesDic.GetTask<DataTable>(this, "UnionBaseGridRightMenus");
//InitializeQueryCondition
Task<MyControl> searchObjTask = cachesDic.AddTask(this, "SearchObj", new Task<MyControl>(() =>
{
DataTable queryTable = customQueryFieldsTask.Result;
bool fixedQuery = queryTable == null || queryTable.Rows.Count == 0;
if (MrpClickMenus == null && mrpClickMenusTask != null)
{
MrpClickMenus = mrpClickMenusTask.Result;
}
MyControl myControl = new MyControl(sysModel.MenuSql, gcMain, LeftTreeViewEx, LeftGridEx, _leftGridSearchObj)
{
SpecialLeftTable = this.SpecialLeftTable,
Model = dynamicModel
Model = dynamicModel,
SystemModel = sysModel,
MrpClickMenus = this.MrpClickMenus
};
if (!fixedQuery)
{
@@ -3981,10 +4019,8 @@ namespace Lskj.Control
}
return myControl;
}));
Task<ModuleModel> searchSysModelTask = cachesDic.AddTask(pl_top_search, "SysModel", new Task<ModuleModel>(() =>
{
return new ModuleModel(MainImpl.GetSystemdllTab(dynamicModel.ModuleCode));
}));
// 搜索区域与当前模块共享同一个模块配置任务,避免再次查询模块信息。
cachesDic.AddTask(pl_top_search, "SysModel", sysModelTask);
//Task<DataTable> searchBaseGridRightMenusTask = cachesDic.AddTask(pl_top_search, "BaseGridRightMenus", new Task<DataTable>(() =>
//{
// return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
+1 -1
View File
@@ -2743,7 +2743,7 @@ namespace Lskj.Control
BaseUserControl baseControl = this.ControlObj.FindControl(PrimaryKey);
if (baseControl != null)
{
this.ControlObj.CopyControlValue();
this.ControlObj.CopyControlValue(this.SysModel.CancelCopyAssociation);
baseControl.EditText = BaseImpl.GetDefaultValue(baseControl.Model.Default, ParentKey);
lteSpeciesNo.TextEdit.EditValue = this.ParentKey;
@@ -466,7 +466,8 @@ namespace Lskj.Control.MultiModelLookUp
}
}
}
SetCustomColumns();
//SetCustomColumns();
}
#endregion
#region
@@ -481,7 +482,7 @@ namespace Lskj.Control.MultiModelLookUp
/// </summary>
private void SetCustomColumns()
{
if (string.IsNullOrEmpty(this.CurrentOperColumnKey) || !BaseImpl.HasExistsTable(ResourceKeys.SettingTableName)) return;
if (string.IsNullOrEmpty(this.CurrentOperColumnKey)) return;
DataTable customTable = this.gcMain.GridView.GetCustomColumnByDatabase(this.CurrentOperColumnKey);
if (customTable != null && customTable.Rows.Count > 0)
+48 -15
View File
@@ -211,17 +211,17 @@ namespace Lskj.Control
g.SetGridViewDataSource(table);
break;
/* ③ Tag 是面板/其它容器,递归找内部网格 ------------------------ */
/* ③ 图表控件:需先于通用容器判断,避免绑定到图表内部隐藏网格 -- */
case ChartControlEx chartEx:
chartEx.CreateChart(table);
break;
/* ④ Tag 是面板/其它容器,递归找内部网格 ------------------------ */
case System.Windows.Forms.Control container when FindGridControlEx(container) is GridControlEx g2:
g2.LastSearchSql = lastSql ?? g2.LastSearchSql;
g2.SetGridViewDataSource(table);
break;
/* ④ 图表控件 ---------------------------------------------------- */
case ChartControlEx chartEx:
chartEx.CreateChart(table);
break;
/* ⑤ 其它控件无需绑定 ------------------------------------------- */
default:
break;
@@ -501,6 +501,14 @@ namespace Lskj.Control
Dictionary<object, Hashtable> dataCaches = Model?.DataCaches;
// 普通 ModuleGridEx 明细使用同一个父模块主键,避免同步加载时每个明细重复查询。
bool hasModuleGridDetail = Model != null && gridDetail.Any(model => IsModuleGridDetail(model, gridDetail, isGridmerge));
string parentPrimaryKey = null;
if (hasModuleGridDetail && !dataCaches.GetValue(this, "ParentPrimaryKey", out parentPrimaryKey))
{
parentPrimaryKey = BaseImpl.GetBasePrimaryKey(Model.ModuleCode);
}
this.DetaiName = string.Empty;
foreach (GridDetailModel model in gridDetail)
@@ -520,7 +528,7 @@ namespace Lskj.Control
page.SizeChanged += OnPageSizeChanged;
// 2️⃣ 先生成“左侧”父明细控件
System.Windows.Forms.Control leftCtrl = CreateDetailControl(page, model, dataCaches);
System.Windows.Forms.Control leftCtrl = CreateDetailControl(page, model, dataCaches, true, null, hasModuleGridDetail, parentPrimaryKey);
int position = int.TryParse(IniHelper.Read($"base_TabPageMain_{model.Id}"), out int value) ? value : 0; // 0 是转换失败时的默认值
if (hasRight && isGridmerge)
{
@@ -559,7 +567,7 @@ namespace Lskj.Control
foreach (var child in rightChildren.OrderBy(c => c.Orderid))
{
XtraTabPage childPage = new XtraTabPage { Text = child.DetailName };
System.Windows.Forms.Control childCtrl = CreateDetailControl(childPage, child, dataCaches, true, leftControl);
System.Windows.Forms.Control childCtrl = CreateDetailControl(childPage, child, dataCaches, true, leftControl, hasModuleGridDetail, parentPrimaryKey);
childPage.Controls.Add(childCtrl);
rightTab.TabPages.Add(childPage);
_rightSideTabPages.Add(childPage);
@@ -605,6 +613,21 @@ namespace Lskj.Control
}
}
/// <summary>
/// 判断明细配置是否会创建普通 ModuleGridEx 控件。
/// </summary>
private static bool IsModuleGridDetail(GridDetailModel model, List<GridDetailModel> gridDetail, bool isGridmerge)
{
if (model == null || model.IsChart || model.IsExcel || model.IsWebView || model.IsWebView2 || model.IsWebView3 ||
model.IsSched || (model.IsAddPanel && isGridmerge) || model.IsDetailView)
{
return false;
}
int sameDetailCount = gridDetail.Count(item => item.DetailName.Equals(model.DetailName));
return !(model.IsReadOnly && sameDetailCount == 1) && !(sameDetailCount > 1 && isGridmerge);
}
@@ -989,6 +1012,7 @@ namespace Lskj.Control
this.isMrpDetail = true;
gridEx.VisibleMrpSearchPanel = true;
}
gridEx.MrpClickMenus = rightDt;
gridEx.VisibleOperPanel = !model.IsReadOnly;
gridEx.InitializeControl(model.SystemModel, dyncModel);
gridEx.GridControlObj.Tag = model;
@@ -1106,7 +1130,7 @@ namespace Lskj.Control
/// <param name="dataCaches"></param>
/// <param name="isGridmerge"></param>
/// <returns></returns>
private System.Windows.Forms.Control CreateDetailControl(System.Windows.Forms.Control parentControl, GridDetailModel model, Dictionary<object, Hashtable> dataCaches, bool isGridmerge = true, GridControlEx leftGridControlEx =null)
private System.Windows.Forms.Control CreateDetailControl(System.Windows.Forms.Control parentControl, GridDetailModel model, Dictionary<object, Hashtable> dataCaches, bool isGridmerge = true, GridControlEx leftGridControlEx = null, bool hasParentPrimaryKey = false, string parentPrimaryKey = null)
{
GridDetailModel[] isMeage = _gridDetail.Cast<GridDetailModel>().Where(x => x.DetailName.Equals(model.DetailName)).ToArray();
@@ -1441,8 +1465,11 @@ namespace Lskj.Control
if (Model != null)
{
if (!dataCaches.GetValue(gridEx, "ParentPrimaryKey", out string primaryKey))
string primaryKey = parentPrimaryKey;
if (!hasParentPrimaryKey && !dataCaches.GetValue(gridEx, "ParentPrimaryKey", out primaryKey))
{
primaryKey = BaseImpl.GetBasePrimaryKey(Model.ModuleCode);
}
model.SystemModel.ParmaryKey = primaryKey;
}
@@ -1465,6 +1492,7 @@ namespace Lskj.Control
isMrpDetail = true;
gridEx.VisibleMrpSearchPanel = true;
}
gridEx.MrpClickMenus = rightDt;
gridEx.VisibleOperPanel = !model.IsReadOnly;
if (model.HideBottomPanel|| model.Library.Equals("Lskj.Report.dll", StringComparison.OrdinalIgnoreCase))
@@ -1600,6 +1628,15 @@ namespace Lskj.Control
Task<List<GridDetailModel>> detailsTask = cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
DynamicModel dynamicModel = dynamicModelTask.Result;
List<GridDetailModel> details = detailsTask.Result;
// 所有子模块使用同一个父模块主键。优先复用外部主表的查询任务,其他入口只补查一次。
Task<string> parentPrimaryKeyTask = cachesDic.GetTask<string>(this, "ParentPrimaryKey");
if (parentPrimaryKeyTask == null)
{
parentPrimaryKeyTask = cachesDic.AddTask(this, "ParentPrimaryKey", new Task<string>(() =>
{
return BaseImpl.GetBasePrimaryKey(dynamicModel.ModuleCode);
}));
}
string DetaiName = string.Empty;
PageControlsDic.Clear();
foreach (GridDetailModel model in details)
@@ -1778,11 +1815,7 @@ namespace Lskj.Control
}));
if (dynamicModel != null)
{
Task<string> basePrimaryKeyTask = cachesDic.AddTask(gridEx, "ParentPrimaryKey", new Task<string>(() =>
{
string basePrimaryKey = BaseImpl.GetBasePrimaryKey(dynamicModel.ModuleCode);
return basePrimaryKey;
}));
cachesDic.AddTask(gridEx, "ParentPrimaryKey", parentPrimaryKeyTask);
}
Task<DataTable> baseGridRightMenusTask = cachesDic.AddTask(gridEx, "UnionBaseGridRightMenus", new Task<DataTable>(() =>
{
+2 -2
View File
@@ -418,7 +418,7 @@ namespace Lskj.Control
if (model.IsStrickOut) fontStyle = fontStyle | FontStyle.Strikeout;
if (model.IsUnderLine) fontStyle = fontStyle | FontStyle.Underline;
e.Appearance.Font = new Font(e.Appearance.Font, fontStyle);
e.Appearance.FontStyleDelta = fontStyle;
}
}
catch (Exception)
@@ -471,7 +471,7 @@ namespace Lskj.Control
if (model.IsStrickOut) fontStyle = fontStyle | FontStyle.Strikeout;
if (model.IsUnderLine) fontStyle = fontStyle | FontStyle.Underline;
e.Appearance.Font = new Font(e.Appearance.Font, fontStyle);
e.Appearance.FontStyleDelta = fontStyle;
}
}
catch (Exception)
+2
View File
@@ -629,6 +629,8 @@ namespace Lskj.Main.Model
}
ERPInfo.Instance.selectFormModleId = module.Id;
// 每次打开顶层模块时重新记录本次初始化使用的表、字段参数。
InitialParamCache.Clear();
IForm iform = FormHelper.LoadDllForm(module.DllName, args);
// 菜单打开的模块默认最大化,界面FormState设置为Normal模式,否则会出现界面不是全屏,会显示默认阴影界面
//iform.SubForm.WindowState = _frmMain.WindowState;
+5 -1
View File
@@ -1062,6 +1062,10 @@ namespace Lskj.Model
/// 下方高
/// </summary>
public int BottomHeight;
/// <summary>
/// 取消复制新增时触发关联(默认触发,设置为1不触发。ModulePanelEx的复制新增按钮)
/// </summary>
public bool CancelCopyAssociation;
#endregion
/// <summary>
@@ -1258,7 +1262,7 @@ namespace Lskj.Model
this.ModuleFrameHeight = rowItem.Table.Columns.Contains("ModuleFrameHeight") && !string.IsNullOrEmpty(rowItem["ModuleFrameHeight"] + "") ? Convert.ToInt32(rowItem["ModuleFrameHeight"] + "") : 0;
this.ModuleFrameWidth = rowItem.Table.Columns.Contains("ModuleFrameWidth") && !string.IsNullOrEmpty(rowItem["ModuleFrameWidth"] + "") ? Convert.ToInt32(rowItem["ModuleFrameWidth"] + "") : 0;
this.BottomHeight = rowItem.Table.Columns.Contains("BottomHeight") && !string.IsNullOrEmpty(rowItem["BottomHeight"] + "") ? Convert.ToInt32(rowItem["BottomHeight"] + "") : 0;
this.CancelCopyAssociation = rowItem.Table.Columns.Contains("CancelCopyAssociation") ? !"1".Equals(rowItem["CancelCopyAssociation"] + "") : true;
}
}
}
+3 -1
View File
@@ -473,6 +473,7 @@ namespace Lskj.PubBill
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);
@@ -688,6 +689,7 @@ namespace Lskj.PubBill
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);
@@ -975,7 +977,7 @@ namespace Lskj.PubBill
}
if (this.BillModel.CanImport)
{
this.pmBillExp.AddItems(new BarItem[] { _itemImport, _itemImportUpdate });
this.pmBillExp.AddItems(new BarItem[] { _itemImport });//_itemImportUpdate
}
//分配
this.pmFP.AddItems(new BarItem[] { itemFPBatch });
+27 -1
View File
@@ -211,7 +211,7 @@ namespace Lskj.PubModuleDetail
Dictionary<object, Hashtable> dataCaches =
Model != null ? Model.DataCaches : null;
if (dataCaches == null)
if (dataCaches == null || !AreDataCacheTasksCompleted(dataCaches))
{
return;
}
@@ -262,5 +262,31 @@ namespace Lskj.PubModuleDetail
}
}
}
/// <summary>
/// 并行初始化仍在运行时不能清空缓存字典,后台任务还会读取或追加其中的数据。
/// </summary>
private static bool AreDataCacheTasksCompleted(Dictionary<object, Hashtable> dataCaches)
{
try
{
foreach (Hashtable cacheValues in dataCaches.Values)
{
foreach (object value in cacheValues.Values)
{
Task task = value as Task;
if (task != null && !task.IsCompleted)
{
return false;
}
}
}
return true;
}
catch (InvalidOperationException)
{
return false;
}
}
}
}