fix: 收敛旧控件资源与后台线程生命周期

This commit is contained in:
2026-08-11 14:12:18 +08:00
parent f1ce6ff658
commit a9c986f9d5
20 changed files with 1145 additions and 380 deletions
@@ -52,6 +52,13 @@ namespace Lskj.Control
/// </summary>
private bool _working = false;
private List<string> _queryQueue = new List<string>();
private LatestValueWorker<PopupQueryRequest> _queryWorker;
private sealed class PopupQueryRequest
{
public string SqlValue;
public bool IsNewPopup;
}
/// <summary>
/// The _popup
/// </summary>
@@ -246,9 +253,7 @@ namespace Lskj.Control
public void OnAutoPopupShow()
{
this.CalcPopupLocation();
Thread queryThread = new Thread(CalcPopupSize);
queryThread.IsBackground = true;
queryThread.Start(Popup);
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
//// 在主线程中显示等待对话框,并在后台线程中执行查询和数据绑定
//Task.Run(() =>
@@ -339,6 +344,7 @@ namespace Lskj.Control
public AutoGridLookUp()
{
InitializePopup();
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
InitializeEvent();
this.Disposed += OnDisposed;
}
@@ -390,9 +396,7 @@ namespace Lskj.Control
this.ShowPopup();
}
Thread queryThread = new Thread(CalcPopupSize);
queryThread.IsBackground = true;
queryThread.Start(Popup);
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
}
/// <summary>
/// <para>说明:计算弹出控件位置</para>
@@ -600,16 +604,7 @@ namespace Lskj.Control
sqlValue = ControlObj.ReplaceControlValue(sourceSql);
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sqlValue);
}
else
{
this._queryQueue.Add(sqlValue);
}
QueuePopupQuery(sqlValue, false);
}
}
@@ -709,9 +704,9 @@ namespace Lskj.Control
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
sql = ReplaceHelper.ReplaceParam(sql);
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sql);
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSource,
sql);
this._queryQueue.Clear();
}
@@ -1601,16 +1596,74 @@ namespace Lskj.Control
}
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(sqlValue);
QueuePopupQuery(sqlValue, true);
}
else
{
this._queryQueue.Add(sqlValue);
}
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
{
if (_queryWorker == null || IsDisposed || Disposing)
{
return;
}
_working = true;
if (Popup != null)
{
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
Popup.BottomPanelObj.Visible = true;
Popup.GridControlObj.DataSourceTable().Clear();
}
_queryWorker.Queue(new PopupQueryRequest
{
SqlValue = sqlValue,
IsNewPopup = isNewPopup
});
}
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
{
DateTime beginTime = DateTime.Now;
DataTable table = new DataTable();
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
{
try
{
table = SqlHelper.ExecuteDataTable(request.SqlValue);
}
catch
{
table = new DataTable();
}
}
DateTime endTime = DateTime.Now;
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
{
return;
}
try
{
BeginInvoke(new MethodInvoker(delegate
{
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
{
return;
}
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
string tipMsg = "数据筛选完成.";
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
Popup.GridControlObj.DataSource = table;
_working = false;
CalcFormAndGrid(request != null && request.IsNewPopup);
}));
}
catch (InvalidOperationException)
{
}
}
@@ -1646,9 +1699,9 @@ namespace Lskj.Control
if (this._queryQueue.Count > 0)
{
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(this._queryQueue.Last());
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSourceNew,
this._queryQueue.Last());
this._queryQueue.Clear();
}
else
@@ -1681,6 +1734,13 @@ namespace Lskj.Control
/// <param name="e"></param>
private void OnDisposed(object sender, EventArgs e)
{
if (_queryWorker != null)
{
_queryWorker.Dispose();
_queryWorker = null;
}
_working = false;
_queryQueue.Clear();
this._popup?.Dispose();
this._popup = null;
}
@@ -46,6 +46,13 @@ namespace Lskj.Control
/// </summary>
private bool _working = false;
private List<string> _queryQueue = new List<string>();
private LatestValueWorker<PopupQueryRequest> _queryWorker;
private sealed class PopupQueryRequest
{
public string SqlValue;
public bool IsNewPopup;
}
/// <summary>
/// The _popup
/// </summary>
@@ -318,6 +325,7 @@ namespace Lskj.Control
public AutoGridRevLookUp()
{
InitializePopup();
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
InitializeEvent();
this.Disposed += OnDisposed;
}
@@ -360,9 +368,7 @@ namespace Lskj.Control
}
private void CalcFormAndGrid()
{
Thread queryThread = new Thread(CalcPopupSize);
queryThread.IsBackground = true;
queryThread.Start(Popup);
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
}
/// <summary>
/// <para>说明:计算弹出控件位置</para>
@@ -527,16 +533,7 @@ namespace Lskj.Control
}
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sqlValue);
}
else
{
this._queryQueue.Add(sqlValue);
}
QueuePopupQuery(sqlValue, false);
}
}
@@ -627,9 +624,9 @@ namespace Lskj.Control
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
sql = ReplaceHelper.ReplaceParam(sql);
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sql);
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSource,
sql);
this._queryQueue.Clear();
}
else
@@ -1022,15 +1019,23 @@ namespace Lskj.Control
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void OnAutoGridLookUpGotFocus(object sender, EventArgs e)
{
System.Threading.Thread thread = new Thread(() =>
ThreadPool.QueueUserWorkItem(delegate
{
while (!this.IsSetDataSource)
{
if (IsDisposed || Disposing)
{
return;
}
Thread.Sleep(10);
}
if (IsDisposed || Disposing)
{
return;
}
this.HandPopupSqlValue(this.Text);
ShowPopup();
});
thread.Start();
}
/// <summary>
/// 鼠标单击控件时
@@ -1041,15 +1046,23 @@ namespace Lskj.Control
{
if (this._popup.Visible == false)
{
System.Threading.Thread thread = new Thread(() =>
ThreadPool.QueueUserWorkItem(delegate
{
while (!this.IsSetDataSource)
{
if (IsDisposed || Disposing)
{
return;
}
Thread.Sleep(10);
}
if (IsDisposed || Disposing)
{
return;
}
this.HandPopupSqlValue(this.Text);
ShowPopup();
});
thread.Start();
}
}
/// <summary>
@@ -1327,16 +1340,77 @@ namespace Lskj.Control
}
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(sqlValue);
QueuePopupQuery(sqlValue, true);
}
else
{
this._queryQueue.Add(sqlValue);
}
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
{
if (_queryWorker == null || IsDisposed || Disposing)
{
return;
}
_working = true;
if (Popup != null)
{
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
Popup.BottomPanelObj.Visible = true;
Popup.GridControlObj.DataSourceTable().Clear();
}
_queryWorker.Queue(new PopupQueryRequest
{
SqlValue = sqlValue,
IsNewPopup = isNewPopup
});
}
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
{
DateTime beginTime = DateTime.Now;
DataTable table = new DataTable();
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
{
try
{
table = SqlHelper.ExecuteDataTable(request.SqlValue);
}
catch
{
table = new DataTable();
}
}
DateTime endTime = DateTime.Now;
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
{
return;
}
try
{
BeginInvoke(new MethodInvoker(delegate
{
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
{
return;
}
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
string tipMsg = "数据筛选完成.";
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
Popup.GridControlObj.DataSource = table;
_working = false;
if (request != null && !request.IsNewPopup)
{
CalcFormAndGrid();
}
}));
}
catch (InvalidOperationException)
{
}
}
private void RefreshPopupDataSourceNew(object sqlValue)
@@ -1372,9 +1446,9 @@ namespace Lskj.Control
if (this._queryQueue.Count > 0)
{
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(this._queryQueue.Last());
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSourceNew,
this._queryQueue.Last());
this._queryQueue.Clear();
}
@@ -1419,6 +1493,13 @@ namespace Lskj.Control
/// <param name="e"></param>
private void OnDisposed(object sender, EventArgs e)
{
if (_queryWorker != null)
{
_queryWorker.Dispose();
_queryWorker = null;
}
_working = false;
_queryQueue.Clear();
this._popup?.Dispose();
this._popup = null;
}
@@ -46,6 +46,13 @@ namespace Lskj.Control
/// </summary>
private bool _working = false;
private List<string> _queryQueue = new List<string>();
private LatestValueWorker<PopupQueryRequest> _queryWorker;
private sealed class PopupQueryRequest
{
public string SqlValue;
public bool IsNewPopup;
}
/// <summary>
/// The _popup
/// </summary>
@@ -307,7 +314,9 @@ namespace Lskj.Control
{
InitializeComponent();
InitializePopup();
_queryWorker = new LatestValueWorker<PopupQueryRequest>(ExecuteLatestPopupQuery);
InitializeEvent();
this.Disposed += OnDisposed;
//this.Properties.Buttons[0].Kind = DevExpress.XtraEditors.Controls.ButtonPredefines.Down;
}
@@ -361,9 +370,7 @@ namespace Lskj.Control
this.ShowPopup();
}
Thread queryThread = new Thread(CalcPopupSize);
queryThread.IsBackground = true;
queryThread.Start(Popup);
ThreadPool.QueueUserWorkItem(CalcPopupSize, Popup);
}
/// <summary>
/// <para>说明:计算弹出控件位置</para>
@@ -551,16 +558,7 @@ namespace Lskj.Control
sqlValue = ControlObj.ReplaceControlValue(sourceSql);
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sqlValue);
}
else
{
this._queryQueue.Add(sqlValue);
}
QueuePopupQuery(sqlValue, false);
}
}
@@ -656,9 +654,9 @@ namespace Lskj.Control
string sql = MainImpl.GetDefaultValue(this._queryQueue.Last());
sql = ReplaceHelper.ReplaceParam(sql);
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSource));
thread.IsBackground = true;
thread.Start(sql);
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSource,
sql);
this._queryQueue.Clear();
}
@@ -1403,16 +1401,77 @@ namespace Lskj.Control
sqlValue = ControlObj.ReplaceControlValue(sourceSql.Replace("#", ""));
}
if (!this._working)
{
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(sqlValue);
QueuePopupQuery(sqlValue, true);
}
else
{
this._queryQueue.Add(sqlValue);
}
private void QueuePopupQuery(string sqlValue, bool isNewPopup)
{
if (_queryWorker == null || IsDisposed || Disposing)
{
return;
}
_working = true;
if (Popup != null)
{
Popup.LabelObj.Text = "正在筛选数据,请稍后...";
Popup.BottomPanelObj.Visible = true;
Popup.GridControlObj.DataSourceTable().Clear();
}
_queryWorker.Queue(new PopupQueryRequest
{
SqlValue = sqlValue,
IsNewPopup = isNewPopup
});
}
private void ExecuteLatestPopupQuery(PopupQueryRequest request, int version)
{
DateTime beginTime = DateTime.Now;
DataTable table = new DataTable();
if (request != null && !string.IsNullOrWhiteSpace(request.SqlValue))
{
try
{
table = SqlHelper.ExecuteDataTable(request.SqlValue);
}
catch
{
table = new DataTable();
}
}
DateTime endTime = DateTime.Now;
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || !IsHandleCreated)
{
return;
}
try
{
BeginInvoke(new MethodInvoker(delegate
{
if (_queryWorker == null || !_queryWorker.IsCurrent(version) || IsDisposed || Disposing || Popup == null)
{
return;
}
int second = Convert.ToInt32((endTime - beginTime).TotalSeconds);
string tipMsg = "数据筛选完成.";
Popup.LabelObj.Text = second > 0 ? string.Format(tipMsg + "(耗时{0}秒)", second) : tipMsg;
Popup.GridControlObj.DataSource = table;
_working = false;
if (request != null && !request.IsNewPopup)
{
CalcFormAndGrid();
}
}));
}
catch (InvalidOperationException)
{
}
}
@@ -1449,9 +1508,9 @@ namespace Lskj.Control
if (this._queryQueue.Count > 0)
{
// 在检索过程中还存在输入数据,则拿最后一次数据在进行匹配一次
Thread thread = new Thread(new ParameterizedThreadStart(RefreshPopupDataSourceNew));
thread.IsBackground = true;
thread.Start(this._queryQueue.Last());
ThreadPool.QueueUserWorkItem(
RefreshPopupDataSourceNew,
this._queryQueue.Last());
this._queryQueue.Clear();
}
@@ -1478,5 +1537,21 @@ namespace Lskj.Control
}
}
private void OnDisposed(object sender, EventArgs e)
{
if (_queryWorker != null)
{
_queryWorker.Dispose();
_queryWorker = null;
}
_working = false;
_queryQueue.Clear();
if (_popup != null)
{
_popup.Dispose();
_popup = null;
}
}
}
}
+3 -1
View File
@@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.pl_buttom = new DevExpress.XtraEditors.PanelControl();
this.panelControl1 = new DevExpress.XtraEditors.PanelControl();
this.btnAdd = new DevExpress.XtraEditors.SimpleButton();
@@ -35,7 +36,7 @@
this.btnDel = new DevExpress.XtraEditors.SimpleButton();
this.btnSave = new DevExpress.XtraEditors.SimpleButton();
this.spreadsheetControl1 = new DevExpress.XtraSpreadsheet.SpreadsheetControl();
this.barManager1 = new DevExpress.XtraBars.BarManager();
this.barManager1 = new DevExpress.XtraBars.BarManager(this.components);
this.commonBar1 = new DevExpress.XtraSpreadsheet.UI.CommonBar();
this.spreadsheetCommandBarButtonItem1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem2 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
@@ -51,6 +52,7 @@
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
this.spreadsheetBarController1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController();
this.components.Add(this.spreadsheetBarController1);
((System.ComponentModel.ISupportInitialize)(this.pl_buttom)).BeginInit();
this.pl_buttom.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).BeginInit();
+12 -8
View File
@@ -1331,15 +1331,17 @@ namespace Lskj.Control
/// <returns></returns>
static int CalcIndicatorBestWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
{
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
SizeF sizeF = new SizeF();
int count = view.TopRowIndex + ((DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo)view.GetViewInfo()).RowsInfo.Count;
if (count == 0)
{
count = 30;
}
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
return Convert.ToInt32(sizeF.Width) + 20;
int textWidth = TextRenderer.MeasureText(
count.ToString(),
view.Appearance.Row.Font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
return textWidth + 20;
}
/// <summary>
/// 计算默认的宽度
@@ -1349,16 +1351,18 @@ namespace Lskj.Control
static int CalcIndicatorDefaultWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
{
var grid = view.GridControl;
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
SizeF sizeF = new SizeF();
int rowHeight = 22;//22是Row的估计高度
if (view.RowHeight > 0)
{
rowHeight = view.RowHeight;
}
int count = grid != null ? grid.Height / rowHeight : 30;
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
return Convert.ToInt32(sizeF.Width) + 20;
int textWidth = TextRenderer.MeasureText(
count.ToString(),
view.Appearance.Row.Font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
return textWidth + 20;
}
#endregion
#region
+5 -1
View File
@@ -13,10 +13,14 @@
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
if (disposing)
{
DisposeGridResources();
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
+268 -63
View File
@@ -73,10 +73,6 @@ 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;
@@ -201,6 +197,13 @@ namespace Lskj.Control
protected bool mLoading = false;
protected Timer mTimer = new Timer();
private bool _gridResourcesDisposed;
private const int BarcodeImageCacheLimit = 200;
private readonly Dictionary<string, Image> _barcodeImageCache =
new Dictionary<string, Image>(StringComparer.Ordinal);
private readonly Queue<string> _barcodeImageOrder = new Queue<string>();
private readonly Dictionary<string, Image> _rightMenuButtonImages =
new Dictionary<string, Image>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// 配置有数据源的控件对象
/// </summary>
@@ -299,6 +302,7 @@ namespace Lskj.Control
/// 表格列为会计模块
/// </summary>
private AmountCellRender cellHelper;
private ToolTipController _mainGridToolTipController;
/// <summary>
/// 合并求和时,前一行的内容
/// </summary>
@@ -524,10 +528,10 @@ namespace Lskj.Control
this.gridView.DataSourceChanged += new EventHandler(OnGridDataSourceChanged);
cellHelper = new AmountCellRender(this.gridView);
//鼠标悬浮提示框
ToolTipController MainGvTool = new ToolTipController();
MainGvTool.AutoPopDelay = 1000000;//提示框显示时间 10分钟
MainGvTool.BeforeShow += new ToolTipControllerBeforeShowEventHandler(MainGvTool_BeforeShow);
this.gridControl.ToolTipController = MainGvTool;
_mainGridToolTipController = new ToolTipController();
_mainGridToolTipController.AutoPopDelay = 1000000;//提示框显示时间 10分钟
_mainGridToolTipController.BeforeShow += new ToolTipControllerBeforeShowEventHandler(MainGvTool_BeforeShow);
this.gridControl.ToolTipController = _mainGridToolTipController;
//this.gridView.PopupMenuShowing += new PopupMenuShowingEventHandler(OnGridView_PopupMenuShowing);//添加Footer菜单选项
this.gridView.Click += new EventHandler(OnGridView_Click);//点击复制Footer数据信息
if (SystemInfo.Instance.SelectColorHighlight)
@@ -556,6 +560,103 @@ namespace Lskj.Control
this.gridView.MouseWheel += GridView_MouseWheel;
}
private void DisposeGridResources()
{
if (_gridResourcesDisposed)
{
return;
}
_gridResourcesDisposed = true;
StopColumnSourceTimer();
if (mTimer != null)
{
mTimer.Dispose();
mTimer = null;
}
DisposeColumnImageCaches(ColumnList);
DisposeRightMenuButtonImages();
ClearBarcodeImageCache();
mControlSourceDic.Clear();
mControlList.Clear();
ColumnList.Clear();
AutoPadDataReleColList.Clear();
FrozenColumns.Clear();
ImageList.Clear();
RepeatedVerificationNames.Clear();
PromptMessage.Clear();
if (_mainGridToolTipController != null)
{
_mainGridToolTipController.BeforeShow -= MainGvTool_BeforeShow;
if (gridControl != null)
{
gridControl.ToolTipController = null;
}
_mainGridToolTipController.Dispose();
_mainGridToolTipController = null;
}
}
private void PrepareForColumnRebuild()
{
StopColumnSourceTimer();
DisposeColumnImageCaches(ColumnList);
DisposeRightMenuButtonImages();
ClearBarcodeImageCache();
GridView.Columns.Clear();
GridView.GroupSummary.Clear();
GridView.OptionsView.ShowFooter = false;
DisposeRepositoryItems();
ColumnList.Clear();
AutoPadDataReleColList.Clear();
FrozenColumns.Clear();
ImageList.Clear();
RepeatedVerificationNames.Clear();
PromptMessage.Clear();
mControlList.Clear();
mControlSourceDic.Clear();
isFirstVisableCol = true;
mLoading = false;
}
private void DisposeRepositoryItems()
{
RepositoryItem[] repositoryItems = gridControl.RepositoryItems
.Cast<RepositoryItem>()
.ToArray();
gridControl.RepositoryItems.Clear();
foreach (RepositoryItem repositoryItem in repositoryItems)
{
repositoryItem.Dispose();
}
}
private void ScheduleColumnSources()
{
StopColumnSourceTimer();
if (_gridResourcesDisposed)
{
return;
}
mLoading = false;
mTimer.Tick += mTimerTick;
mTimer.Start();
}
private void StopColumnSourceTimer()
{
if (mTimer == null)
{
return;
}
mTimer.Stop();
mTimer.Tick -= mTimerTick;
}
/// <summary>
/// 保存前反写多表头数据源
@@ -1404,13 +1505,11 @@ namespace Lskj.Control
public virtual void SetReadOnlyColumns(DataTable table, string customColumKey = "")
{
Dictionary<object, Hashtable> dataCaches = Model != null ? Model.DataCaches : null;
this.mLoading = false;
this.InitGridColumsTab = table;
this.CustomColumKey = customColumKey;
this.gridColumnsInitialized = false;
this.GridView.Columns.Clear();
this.ColumnList.Clear();
this.selectReturnDisplaySourceCache.Clear();
PrepareForColumnRebuild();
if (table == null) return;
this.gridView.BeginUpdate();
for (int i = 0; i < table.Rows.Count; i++)
@@ -1499,9 +1598,7 @@ namespace Lskj.Control
//this.SetCustomColumns();
this.gridView.EndUpdate();
//延迟加载数据源
this.mLoading = false;
this.mTimer.Tick += new EventHandler(mTimerTick);
this.mTimer.Start();
ScheduleColumnSources();
}
/// <summary>
@@ -1517,7 +1614,8 @@ namespace Lskj.Control
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void mTimerTick(object sender, EventArgs e)
{
if (!mLoading)
StopColumnSourceTimer();
if (!mLoading && !_gridResourcesDisposed && !IsDisposed)
{
mLoading = true;
try
@@ -1537,11 +1635,6 @@ namespace Lskj.Control
mControlSourceDic.Clear();
}
}
else
{
this.mTimer.Stop();
this.mTimer.Dispose();
}
}
private void SetColumnsSource(bool UpdateColumnRefresh = false)
{
@@ -1561,7 +1654,10 @@ namespace Lskj.Control
{
dataTable = BaseImpl.GetDataTableResult(item.SqlSource);
}
Application.DoEvents();
if (_gridResourcesDisposed || IsDisposed)
{
return;
}
if (!item.Visible) continue;
switch (item.FieldType)
{
@@ -1687,9 +1783,8 @@ namespace Lskj.Control
public virtual void SetReadOnlyColumns(DataTable table, string customColumKey, Font font, DefaultBoolean allSort)
{
this.CustomColumKey = customColumKey;
this.GridView.Columns.Clear();
this.ColumnList.Clear();
this.selectReturnDisplaySourceCache.Clear();
PrepareForColumnRebuild();
if (table == null) return;
for (int i = 0; i < table.Rows.Count; i++)
{
@@ -1763,8 +1858,7 @@ namespace Lskj.Control
this.SetCustomColumns(customTable);
// 延迟加载数据源
this.mTimer.Tick += new EventHandler(mTimerTick);
this.mTimer.Start();
ScheduleColumnSources();
}
/// <summary>
/// <para>说明:设置可编辑列</para>
@@ -1779,13 +1873,11 @@ namespace Lskj.Control
/// <param name="customKey">需要显示表格列右键菜单(保存列属性、重置列属性)则传递此值.</param>
public virtual void SetEditColumns(DataTable table, string customColumKey = "")
{
this.mLoading = false;
this.InitGridColumsTab = table;
this.CustomColumKey = customColumKey;
this.gridColumnsInitialized = false;
this.GridView.Columns.Clear();
this.ColumnList.Clear();
this.selectReturnDisplaySourceCache.Clear();
PrepareForColumnRebuild();
if (table == null) return;
Console.WriteLine(DateTime.Now);
@@ -1924,8 +2016,7 @@ namespace Lskj.Control
Console.WriteLine(DateTime.Now);
// 延迟加载数据源
this.mTimer.Tick += new EventHandler(mTimerTick);
this.mTimer.Start();
ScheduleColumnSources();
}
/// <summary>
@@ -5201,11 +5292,10 @@ namespace Lskj.Control
editorButton.Appearance.BackColor = Color.Transparent;
if (!string.IsNullOrEmpty(menuModel.IcoName))
{
Image image = null;
try
{
image = Image.FromFile(Util.PubUtil.GridColumnIco + menuModel.IcoName);
if (image.Width > 30)
Image image = GetRightMenuButtonImage(menuModel.IcoName);
if (image != null && image.Width > 30)
{
picWidth = image.Width;
}
@@ -9451,23 +9541,59 @@ namespace Lskj.Control
//ItemPictureEdit.NullText = " ";
if (ItemPictureEdit != null && !string.IsNullOrWhiteSpace(e.Value + ""))
{
BarcodeSettings settings = new BarcodeSettings();
settings.X = 0.6f;//设置黑白条宽度
settings.ImageHeight = 40;//设置生成的条码图片高度
settings.ImageWidth = 100;//设置生成的条码图片宽度
settings.Type = BarCodeType.Code128;
settings.Data = e.Value + "";//设置条码数据
settings.ShowTextOnBottom = true;//设置数据文本显示在条码底部*/
settings.ShowText = true;//设置数据文本显示
BarCodeGenerator bargenerator = new BarCodeGenerator(settings);
Image barcodeimage = bargenerator.GenerateImage();
e.Value = barcodeimage;
e.Value = GetOrCreateBarcodeImage(e.Value + "");
}
// e.Value = e.Value + "";
e.Handled = true;
}
private Image GetOrCreateBarcodeImage(string value)
{
Image image;
if (_barcodeImageCache.TryGetValue(value, out image))
{
return image;
}
BarcodeSettings settings = new BarcodeSettings();
settings.X = 0.6f;
settings.ImageHeight = 40;
settings.ImageWidth = 100;
settings.Type = BarCodeType.Code128;
settings.Data = value;
settings.ShowTextOnBottom = true;
settings.ShowText = true;
BarCodeGenerator barcodeGenerator = new BarCodeGenerator(settings);
image = barcodeGenerator.GenerateImage();
while (_barcodeImageOrder.Count >= BarcodeImageCacheLimit)
{
string oldestValue = _barcodeImageOrder.Dequeue();
Image oldestImage;
if (_barcodeImageCache.TryGetValue(oldestValue, out oldestImage))
{
_barcodeImageCache.Remove(oldestValue);
oldestImage.Dispose();
}
}
_barcodeImageCache[value] = image;
_barcodeImageOrder.Enqueue(value);
return image;
}
private void ClearBarcodeImageCache()
{
foreach (Image image in _barcodeImageCache.Values)
{
image.Dispose();
}
_barcodeImageCache.Clear();
_barcodeImageOrder.Clear();
}
@@ -9822,15 +9948,44 @@ namespace Lskj.Control
/// </summary>
private void ClearImage()
{
GridColumnCollection gridColumns = this.GridView.Columns;
foreach (GridColumn col in gridColumns)
{
GridColumnModel model = col.Tag as GridColumnModel;
if (model != null && model.FieldType == ControlType.LabPicUrl)
{
model.LabPicUrlImages = new Hashtable();
DisposeColumnImageCaches(
this.GridView.Columns
.Cast<GridColumn>()
.Select(column => column.Tag as GridColumnModel));
ClearBarcodeImageCache();
}
private static void DisposeColumnImageCaches(
IEnumerable<GridColumnModel> columnModels)
{
if (columnModels == null)
{
return;
}
foreach (GridColumnModel model in columnModels.Where(
item => item != null && item.LabPicUrlImages != null))
{
foreach (DictionaryEntry entry in model.LabPicUrlImages)
{
if (!(entry.Value is KeyValuePair<Image, Image> images))
{
continue;
}
if (images.Value != null && !ReferenceEquals(images.Key, images.Value))
{
images.Value.Dispose();
}
if (images.Key != null)
{
images.Key.Dispose();
}
}
model.LabPicUrlImages.Clear();
model.LabPicUrlImages = null;
}
}
@@ -10461,18 +10616,68 @@ namespace Lskj.Control
if (string.IsNullOrEmpty(caption))
return 40; // 空文本默认宽度
using (Bitmap tempBitmap = new Bitmap(1, 1))
using (Graphics g = Graphics.FromImage(tempBitmap))
{
// 测量文本尺寸
SizeF textSize = g.MeasureString(caption, font);
// 计算总宽度 = 文本宽度 + 左右边距
int width = (int)textSize.Width + padding;
// 确保宽度不小于最小值
return Math.Max(width, 40); // 最小宽度40像素
int textWidth = TextRenderer.MeasureText(
caption,
font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
return Math.Max(textWidth + padding, 40);
}
private Image GetRightMenuButtonImage(string imageName)
{
if (string.IsNullOrWhiteSpace(imageName))
{
return null;
}
Image image;
if (_rightMenuButtonImages.TryGetValue(imageName, out image))
{
return image;
}
string imagePath = Path.Combine(Util.PubUtil.GridColumnIco, imageName);
using (Image sourceImage = Image.FromFile(imagePath))
{
image = new Bitmap(sourceImage);
}
_rightMenuButtonImages[imageName] = image;
return image;
}
private void DisposeRightMenuButtonImages()
{
if (_rightMenuButtonImages.Count == 0)
{
return;
}
IEnumerable<RepositoryItemButtonEdit> buttonEditors =
gridControl.RepositoryItems.OfType<RepositoryItemButtonEdit>()
.Concat(gridView.Columns.Cast<GridColumn>()
.Select(column => column.ColumnEdit)
.OfType<RepositoryItemButtonEdit>())
.Distinct();
foreach (RepositoryItemButtonEdit buttonEditor in buttonEditors)
{
foreach (EditorButton button in buttonEditor.Buttons)
{
if (button.Image != null && _rightMenuButtonImages.Values.Any(image => ReferenceEquals(image, button.Image)))
{
button.Image = null;
}
}
}
foreach (Image ownedImage in _rightMenuButtonImages.Values)
{
ownedImage.Dispose();
}
_rightMenuButtonImages.Clear();
}
+5 -3
View File
@@ -160,9 +160,11 @@ namespace Lskj.Control
}
else
{
Graphics g = this.lblText.CreateGraphics();
SizeF sizeF = g.MeasureString(value, this.lblText.Font);
this.plLeft.Width = (int)sizeF.Width + PaddingLeft;
this.plLeft.Width = TextRenderer.MeasureText(
value,
this.lblText.Font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width + PaddingLeft;
}
}
}
+117
View File
@@ -0,0 +1,117 @@
using System;
using System.Threading;
namespace Lskj.Control
{
/// <summary>
/// 串行处理请求,并在繁忙时只保留最后一次请求。
/// 用于输入联想控件,避免每次 TextChanged 都创建独立线程。
/// </summary>
internal sealed class LatestValueWorker<T> : IDisposable
{
private readonly object _syncRoot = new object();
private readonly Action<T, int> _work;
private T _pendingValue;
private bool _hasPendingValue;
private bool _workerRunning;
private bool _disposed;
private int _version;
public LatestValueWorker(Action<T, int> work)
{
if (work == null)
{
throw new ArgumentNullException("work");
}
_work = work;
}
public int Queue(T value)
{
bool startWorker = false;
int version;
lock (_syncRoot)
{
if (_disposed)
{
return -1;
}
version = ++_version;
_pendingValue = value;
_hasPendingValue = true;
if (!_workerRunning)
{
_workerRunning = true;
startWorker = true;
}
}
if (startWorker && !ThreadPool.QueueUserWorkItem(Run))
{
lock (_syncRoot)
{
_workerRunning = false;
}
throw new InvalidOperationException("无法启动输入联想查询任务。");
}
return version;
}
public bool IsCurrent(int version)
{
lock (_syncRoot)
{
return !_disposed && version == _version;
}
}
private void Run(object state)
{
while (true)
{
T value;
int version;
lock (_syncRoot)
{
if (_disposed || !_hasPendingValue)
{
_workerRunning = false;
return;
}
value = _pendingValue;
version = _version;
_pendingValue = default(T);
_hasPendingValue = false;
}
try
{
_work(value, version);
}
catch
{
// 查询异常由控件自身转换为空结果;这里确保工作循环能够继续或退出。
}
}
}
public void Dispose()
{
lock (_syncRoot)
{
_disposed = true;
_hasPendingValue = false;
_pendingValue = default(T);
_version++;
}
}
}
}
@@ -712,6 +712,7 @@
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoGridLookUp\ExtendedReturnModuleSourceResolver.cs" />
<Compile Include="LatestValueWorker.cs" />
<Compile Include="AutoGridLookUp\LabelExtendedReturnSearchEdit.cs">
<SubType>UserControl</SubType>
</Compile>
@@ -26,8 +26,9 @@ namespace Lskj.Control.Model
/// <summary>
/// 表格拖拽到表格
/// </summary>
public class BandedGridDragGrid
public class BandedGridDragGrid : IDisposable
{
private bool _disposed;
/// <summary>
/// 是否正在拖拽
/// </summary>
@@ -106,6 +107,99 @@ namespace Lskj.Control.Model
this._targetGridView.GridControl.DragEnter += new System.Windows.Forms.DragEventHandler(gridControl_DragEnter);
this._targetGridView.GridControl.DragDrop += new System.Windows.Forms.DragEventHandler(gridControl_DragDrop);
this._targetGridView.GridControl.DragLeave += new EventHandler(gridControl_DragLeave);
this._sourceGridView.Disposed += OnGridViewDisposed;
if (!ReferenceEquals(this._sourceGridView, this._targetGridView))
{
this._targetGridView.Disposed += OnGridViewDisposed;
}
}
private void OnGridViewDisposed(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
BandedGridView sourceGridView = _sourceGridView;
GridView targetGridView = _targetGridView;
if (sourceGridView != null)
{
sourceGridView.MouseDown -= sourceGridView_MouseDown;
sourceGridView.MouseMove -= sourceGridView_MouseMove;
sourceGridView.MouseUp -= sourceGridView_MouseUp;
sourceGridView.RowClick -= OnRowClick;
sourceGridView.Disposed -= OnGridViewDisposed;
}
if (targetGridView != null)
{
if (targetGridView.GridControl != null)
{
targetGridView.GridControl.DragOver -= gridControl_DragOver;
targetGridView.GridControl.DragEnter -= gridControl_DragEnter;
targetGridView.GridControl.DragDrop -= gridControl_DragDrop;
targetGridView.GridControl.DragLeave -= gridControl_DragLeave;
}
if (!ReferenceEquals(sourceGridView, targetGridView))
{
targetGridView.Disposed -= OnGridViewDisposed;
}
}
RemoveRegistration(
StaticBandedControl.BandedGridViewDragGridDic,
sourceGridView,
this);
RemoveRegistration(
StaticBandedControl.BandedTargetViewDragGridDic,
targetGridView,
this);
if (ReferenceEquals(
StaticBandedControl.SourceDragBandedGridView,
sourceGridView))
{
StaticBandedControl.SourceDragBandedGridView = null;
}
OnDragComplete = null;
DragHander.Clear();
_hitInfo = null;
_sourceGridView = null;
_targetGridView = null;
}
private static void RemoveRegistration<TKey>(
Dictionary<TKey, List<BandedGridDragGrid>> registrations,
TKey key,
BandedGridDragGrid registration)
where TKey : class
{
if (key == null)
{
return;
}
List<BandedGridDragGrid> registrationsForView;
if (!registrations.TryGetValue(key, out registrationsForView))
{
return;
}
registrationsForView.Remove(registration);
if (registrationsForView.Count == 0)
{
registrations.Remove(key);
}
}
/// <summary>
/// 点击时候判断位置
+93 -1
View File
@@ -29,8 +29,9 @@ namespace Lskj.Control.Model
/// <summary>
/// 表格拖拽到表格
/// </summary>
public class GridDragGrid
public class GridDragGrid : IDisposable
{
private bool _disposed;
/// <summary>
/// 是否正在拖拽
/// </summary>
@@ -119,6 +120,97 @@ namespace Lskj.Control.Model
this._targetGridView.GridControl.DragEnter += new System.Windows.Forms.DragEventHandler(gridControl_DragEnter);
this._targetGridView.GridControl.DragDrop += new System.Windows.Forms.DragEventHandler(gridControl_DragDrop);
this._targetGridView.GridControl.DragLeave += new EventHandler(gridControl_DragLeave);
this._sourceGridView.Disposed += OnGridViewDisposed;
if (!ReferenceEquals(this._sourceGridView, this._targetGridView))
{
this._targetGridView.Disposed += OnGridViewDisposed;
}
}
private void OnGridViewDisposed(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
GridView sourceGridView = _sourceGridView;
GridView targetGridView = _targetGridView;
if (sourceGridView != null)
{
sourceGridView.MouseDown -= sourceGridView_MouseDown;
sourceGridView.MouseMove -= sourceGridView_MouseMove;
sourceGridView.MouseUp -= sourceGridView_MouseUp;
sourceGridView.RowClick -= OnRowClick;
sourceGridView.Disposed -= OnGridViewDisposed;
}
if (targetGridView != null)
{
if (targetGridView.GridControl != null)
{
targetGridView.GridControl.DragOver -= gridControl_DragOver;
targetGridView.GridControl.DragEnter -= gridControl_DragEnter;
targetGridView.GridControl.DragDrop -= gridControl_DragDrop;
targetGridView.GridControl.DragLeave -= gridControl_DragLeave;
}
if (!ReferenceEquals(sourceGridView, targetGridView))
{
targetGridView.Disposed -= OnGridViewDisposed;
}
}
RemoveRegistration(
StaticControl.GridViewDragGridDic,
sourceGridView,
this);
RemoveRegistration(
StaticControl.TargetViewDragGridDic,
targetGridView,
this);
if (ReferenceEquals(StaticControl.SourceDragGridView, sourceGridView))
{
StaticControl.SourceDragGridView = null;
}
OnDragComplete = null;
DragHander.Clear();
_hitInfo = null;
_sourceGridView = null;
_targetGridView = null;
}
private static void RemoveRegistration<TKey>(
Dictionary<TKey, List<GridDragGrid>> registrations,
TKey key,
GridDragGrid registration)
where TKey : class
{
if (key == null)
{
return;
}
List<GridDragGrid> registrationsForView;
if (!registrations.TryGetValue(key, out registrationsForView))
{
return;
}
registrationsForView.Remove(registration);
if (registrationsForView.Count == 0)
{
registrations.Remove(key);
}
}
/// <summary>
/// 点击时候判断位置
+16 -3
View File
@@ -73,10 +73,23 @@ namespace Lskj.Control.Model
/// </summary>
public static void HideForm()
{
bool isSplashFormVisible = LoadForm.IsSplashFormVisible;
if (isSplashFormVisible)
SplashScreenManager manager = _loadForm;
if (manager == null)
return;
try
{
_loadForm.CloseWaitForm();
if (manager.IsSplashFormVisible)
{
manager.CloseWaitForm();
manager.WaitForSplashFormClose();
}
}
finally
{
manager.Dispose();
if (ReferenceEquals(_loadForm, manager))
_loadForm = null;
}
}
}
+1 -189
View File
@@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.scc_container = new DevExpress.XtraEditors.SplitContainerControl();
this.pl_left = new DevExpress.XtraEditors.PanelControl();
this.pl_left_main = new System.Windows.Forms.Panel();
@@ -38,25 +39,8 @@
this.pl_left_top = new DevExpress.XtraEditors.PanelControl();
this.pl_right = new DevExpress.XtraEditors.PanelControl();
this.moduleGridDetailEx1 = new Lskj.Control.ModuleGridDetailEx();
this.excelControlEx1 = new Lskj.Control.ExcelControlEx();
this.repModelDetailEx = new Lskj.Control.ReplacementDetailEx();
this.MainBodyTab = new DevExpress.XtraTab.XtraTabControl();
this.barManager1 = new DevExpress.XtraBars.BarManager();
this.barDockControlTop = new DevExpress.XtraBars.BarDockControl();
this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
this.barDockControlRight = new DevExpress.XtraBars.BarDockControl();
this.commonBar1 = new DevExpress.XtraSpreadsheet.UI.CommonBar();
this.spreadsheetCommandBarButtonItem1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem2 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem3 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem4 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem5 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem6 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem7 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem8 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetCommandBarButtonItem9 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem();
this.spreadsheetBarController1 = new DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController();
((System.ComponentModel.ISupportInitialize)(this.scc_container)).BeginInit();
this.scc_container.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_left)).BeginInit();
@@ -68,8 +52,6 @@
((System.ComponentModel.ISupportInitialize)(this.pl_right)).BeginInit();
this.pl_right.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.MainBodyTab)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.spreadsheetBarController1)).BeginInit();
this.SuspendLayout();
//
// scc_container
@@ -172,7 +154,6 @@
//
this.pl_right.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_right.Controls.Add(this.moduleGridDetailEx1);
this.pl_right.Controls.Add(this.excelControlEx1);
this.pl_right.Controls.Add(this.repModelDetailEx);
this.pl_right.Controls.Add(this.MainBodyTab);
this.pl_right.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -190,20 +171,6 @@
this.moduleGridDetailEx1.TabIndex = 0;
this.moduleGridDetailEx1.VisibleDetailPanel = true;
//
// excelControlEx1
//
this.excelControlEx1.AddEnabled = true;
this.excelControlEx1.DeleteEnabled = true;
this.excelControlEx1.Dock = System.Windows.Forms.DockStyle.Fill;
this.excelControlEx1.Location = new System.Drawing.Point(0, 0);
this.excelControlEx1.Margin = new System.Windows.Forms.Padding(6);
this.excelControlEx1.Name = "excelControlEx1";
this.excelControlEx1.PrintEnabled = true;
this.excelControlEx1.SaveEnabled = true;
this.excelControlEx1.Size = new System.Drawing.Size(712, 610);
this.excelControlEx1.TabIndex = 1;
this.excelControlEx1.Visible = false;
//
// repModelDetailEx
//
this.repModelDetailEx.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -224,147 +191,11 @@
this.MainBodyTab.TabIndex = 6;
this.MainBodyTab.Visible = false;
//
// barManager1
//
this.barManager1.DockControls.Add(this.barDockControlTop);
this.barManager1.DockControls.Add(this.barDockControlBottom);
this.barManager1.DockControls.Add(this.barDockControlLeft);
this.barManager1.DockControls.Add(this.barDockControlRight);
this.barManager1.Form = this;
this.barManager1.MaxItemId = 9;
//
// barDockControlTop
//
this.barDockControlTop.CausesValidation = false;
this.barDockControlTop.Dock = System.Windows.Forms.DockStyle.Top;
this.barDockControlTop.Location = new System.Drawing.Point(0, 0);
this.barDockControlTop.Size = new System.Drawing.Size(915, 0);
//
// barDockControlBottom
//
this.barDockControlBottom.CausesValidation = false;
this.barDockControlBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.barDockControlBottom.Location = new System.Drawing.Point(0, 610);
this.barDockControlBottom.Size = new System.Drawing.Size(915, 0);
//
// barDockControlLeft
//
this.barDockControlLeft.CausesValidation = false;
this.barDockControlLeft.Dock = System.Windows.Forms.DockStyle.Left;
this.barDockControlLeft.Location = new System.Drawing.Point(0, 0);
this.barDockControlLeft.Size = new System.Drawing.Size(0, 610);
//
// barDockControlRight
//
this.barDockControlRight.CausesValidation = false;
this.barDockControlRight.Dock = System.Windows.Forms.DockStyle.Right;
this.barDockControlRight.Location = new System.Drawing.Point(915, 0);
this.barDockControlRight.Size = new System.Drawing.Size(0, 610);
//
// commonBar1
//
this.commonBar1.BarName = "";
this.commonBar1.Control = null;
this.commonBar1.DockCol = 0;
this.commonBar1.DockRow = 0;
this.commonBar1.FloatLocation = new System.Drawing.Point(339, 195);
this.commonBar1.FloatSize = new System.Drawing.Size(244, 31);
this.commonBar1.Offset = 44;
this.commonBar1.Text = "";
//
// spreadsheetCommandBarButtonItem1
//
this.spreadsheetCommandBarButtonItem1.Caption = "New";
this.spreadsheetCommandBarButtonItem1.CommandName = "FileNew";
this.spreadsheetCommandBarButtonItem1.Enabled = false;
this.spreadsheetCommandBarButtonItem1.Id = 8;
this.spreadsheetCommandBarButtonItem1.Name = "spreadsheetCommandBarButtonItem1";
//
// spreadsheetCommandBarButtonItem2
//
this.spreadsheetCommandBarButtonItem2.Caption = "Open";
this.spreadsheetCommandBarButtonItem2.CommandName = "FileOpen";
this.spreadsheetCommandBarButtonItem2.Enabled = false;
this.spreadsheetCommandBarButtonItem2.Id = 7;
this.spreadsheetCommandBarButtonItem2.Name = "spreadsheetCommandBarButtonItem2";
//
// spreadsheetCommandBarButtonItem3
//
this.spreadsheetCommandBarButtonItem3.Caption = "Save";
this.spreadsheetCommandBarButtonItem3.CommandName = "FileSave";
this.spreadsheetCommandBarButtonItem3.Enabled = false;
this.spreadsheetCommandBarButtonItem3.Id = 6;
this.spreadsheetCommandBarButtonItem3.Name = "spreadsheetCommandBarButtonItem3";
//
// spreadsheetCommandBarButtonItem4
//
this.spreadsheetCommandBarButtonItem4.Caption = "Save As";
this.spreadsheetCommandBarButtonItem4.CommandName = "FileSaveAs";
this.spreadsheetCommandBarButtonItem4.Enabled = false;
this.spreadsheetCommandBarButtonItem4.Id = 5;
this.spreadsheetCommandBarButtonItem4.Name = "spreadsheetCommandBarButtonItem4";
//
// spreadsheetCommandBarButtonItem5
//
this.spreadsheetCommandBarButtonItem5.Caption = "&Quick Print";
this.spreadsheetCommandBarButtonItem5.CommandName = "FileQuickPrint";
this.spreadsheetCommandBarButtonItem5.Enabled = false;
this.spreadsheetCommandBarButtonItem5.Id = 4;
this.spreadsheetCommandBarButtonItem5.Name = "spreadsheetCommandBarButtonItem5";
//
// spreadsheetCommandBarButtonItem6
//
this.spreadsheetCommandBarButtonItem6.Caption = "&Print";
this.spreadsheetCommandBarButtonItem6.CommandName = "FilePrint";
this.spreadsheetCommandBarButtonItem6.Enabled = false;
this.spreadsheetCommandBarButtonItem6.Id = 3;
this.spreadsheetCommandBarButtonItem6.Name = "spreadsheetCommandBarButtonItem6";
//
// spreadsheetCommandBarButtonItem7
//
this.spreadsheetCommandBarButtonItem7.Caption = "Print Pre&view";
this.spreadsheetCommandBarButtonItem7.CommandName = "FilePrintPreview";
this.spreadsheetCommandBarButtonItem7.Enabled = false;
this.spreadsheetCommandBarButtonItem7.Id = 2;
this.spreadsheetCommandBarButtonItem7.Name = "spreadsheetCommandBarButtonItem7";
//
// spreadsheetCommandBarButtonItem8
//
this.spreadsheetCommandBarButtonItem8.Caption = "Undo";
this.spreadsheetCommandBarButtonItem8.CommandName = "FileUndo";
this.spreadsheetCommandBarButtonItem8.Enabled = false;
this.spreadsheetCommandBarButtonItem8.Id = 1;
this.spreadsheetCommandBarButtonItem8.Name = "spreadsheetCommandBarButtonItem8";
//
// spreadsheetCommandBarButtonItem9
//
this.spreadsheetCommandBarButtonItem9.Caption = "Redo";
this.spreadsheetCommandBarButtonItem9.CommandName = "FileRedo";
this.spreadsheetCommandBarButtonItem9.Enabled = false;
this.spreadsheetCommandBarButtonItem9.Id = 0;
this.spreadsheetCommandBarButtonItem9.Name = "spreadsheetCommandBarButtonItem9";
//
// spreadsheetBarController1
//
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem1);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem2);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem3);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem4);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem5);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem6);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem7);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem8);
this.spreadsheetBarController1.BarItems.Add(this.spreadsheetCommandBarButtonItem9);
//
// ModuleEx
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.SystemColors.Control;
this.Controls.Add(this.scc_container);
this.Controls.Add(this.barDockControlLeft);
this.Controls.Add(this.barDockControlRight);
this.Controls.Add(this.barDockControlBottom);
this.Controls.Add(this.barDockControlTop);
this.Name = "ModuleEx";
this.Size = new System.Drawing.Size(915, 610);
((System.ComponentModel.ISupportInitialize)(this.scc_container)).EndInit();
@@ -378,10 +209,7 @@
((System.ComponentModel.ISupportInitialize)(this.pl_right)).EndInit();
this.pl_right.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.MainBodyTab)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.barManager1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.spreadsheetBarController1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
@@ -389,22 +217,6 @@
private DevExpress.XtraEditors.SplitContainerControl scc_container;
private DevExpress.XtraEditors.PanelControl pl_right;
private DevExpress.XtraBars.BarManager barManager1;
private DevExpress.XtraBars.BarDockControl barDockControlTop;
private DevExpress.XtraBars.BarDockControl barDockControlBottom;
private DevExpress.XtraBars.BarDockControl barDockControlLeft;
private DevExpress.XtraBars.BarDockControl barDockControlRight;
private DevExpress.XtraSpreadsheet.UI.CommonBar commonBar1;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem1;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem2;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem3;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem4;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem5;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem6;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem7;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem8;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetCommandBarButtonItem spreadsheetCommandBarButtonItem9;
private DevExpress.XtraSpreadsheet.UI.SpreadsheetBarController spreadsheetBarController1;
private DevExpress.XtraEditors.PanelControl pl_left;
private System.Windows.Forms.Panel pl_left_main;
private DevExpress.XtraEditors.PanelControl pl_gridandtree_container;
+41 -9
View File
@@ -152,6 +152,34 @@ namespace Lskj.Control
InitializeComponent();
}
/// <summary>
/// Excel 控件包含 SpreadsheetControl、BarManager 和命令注册项,
/// 普通表格模块不应在设计器初始化阶段创建这些重型资源。
/// </summary>
private ExcelControlEx EnsureExcelControl()
{
if (this.excelControlEx1 != null && !this.excelControlEx1.IsDisposed)
{
return this.excelControlEx1;
}
this.excelControlEx1 = new ExcelControlEx
{
AddEnabled = true,
DeleteEnabled = true,
Dock = DockStyle.Fill,
Margin = new Padding(6),
Name = "excelControlEx1",
PrintEnabled = true,
SaveEnabled = true,
TabIndex = 1,
Visible = false
};
this.pl_right.Controls.Add(this.excelControlEx1);
this.ExcelControlObj = this.excelControlEx1;
return this.excelControlEx1;
}
/// <summary>
/// <para>说明:创建界面</para>
/// <para>创建人:龚宇超</para>
@@ -284,20 +312,22 @@ namespace Lskj.Control
}
if (this.IsExcel)
{
//由于创建对象时候要注册,所以动态构造这控件不在设计器进行否则表格模式也会弹出注册
// 只有 Excel 模式才创建 Spreadsheet/Bar 相关资源。
ExcelControlEx excelControl = EnsureExcelControl();
this.ModuleGridDetailObj.Visible = false;
this.repModelDetailEx.Visible = false;
this.excelControlEx1.Visible = true;
excelControl.Visible = true;
excelControl.BringToFront();
if (!Model.DataCaches.GetValue(this, "BasePrimaryKey", out SysModel.ParmaryKey))
{
SysModel.ParmaryKey = BaseImpl.GetBasePrimaryKey(this.Model.ModuleCode);
}
this.excelControlEx1.AddEnabled = this.SysModel.AddEnable;
this.excelControlEx1.DeleteEnabled = this.SysModel.DeleteEnable;
this.excelControlEx1.PrintEnabled = !string.IsNullOrWhiteSpace(this.SysModel.PrintFile);
this.excelControlEx1.SaveEnabled = this.SysModel.ModifyEnable;
this.excelControlEx1.CreateFile();
this.excelControlEx1.SaveCallBack += new EventHandler(OnExcelSaveClick);
excelControl.AddEnabled = this.SysModel.AddEnable;
excelControl.DeleteEnabled = this.SysModel.DeleteEnable;
excelControl.PrintEnabled = !string.IsNullOrWhiteSpace(this.SysModel.PrintFile);
excelControl.SaveEnabled = this.SysModel.ModifyEnable;
excelControl.CreateFile();
excelControl.SaveCallBack += new EventHandler(OnExcelSaveClick);
if (!Model.DataCaches.GetValue(this, "BaseGridColumns", out DataTable dtGridColumns))
{
dtGridColumns = BaseModuleImpl.GetBaseGridColumns(this.Model.ModuleCode);
@@ -314,8 +344,10 @@ namespace Lskj.Control
}
else
{
if (this.excelControlEx1 != null)
{
this.excelControlEx1.Visible = false;
}
if (SysModel.isReplacMainDetail == "1")
{
this.ModuleGridDetailObj.Visible = false;
+6 -1
View File
@@ -13,10 +13,15 @@
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
if (disposing)
{
Lskj.Control.Model.PrintUtil.OnAfterPrint -=
new System.EventHandler(OnReportPrintAfter);
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
@@ -111,15 +111,17 @@ namespace Lskj.Control.SiftColControl
/// <returns></returns>
static int CalcIndicatorBestWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
{
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
SizeF sizeF = new SizeF();
int count = view.TopRowIndex + ((DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo)view.GetViewInfo()).RowsInfo.Count;
if (count == 0)
{
count = 30;
}
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
return Convert.ToInt32(sizeF.Width) + 20;
int textWidth = TextRenderer.MeasureText(
count.ToString(),
view.Appearance.Row.Font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
return textWidth + 20;
}
/// <summary>
/// 计算默认的宽度
@@ -129,16 +131,18 @@ namespace Lskj.Control.SiftColControl
static int CalcIndicatorDefaultWidth(DevExpress.XtraGrid.Views.Grid.GridView view)
{
var grid = view.GridControl;
Graphics graphics = new System.Windows.Forms.Control().CreateGraphics();
SizeF sizeF = new SizeF();
int rowHeight = 22;//22是Row的估计高度
if (view.RowHeight > 0)
{
rowHeight = view.RowHeight;
}
int count = grid != null ? grid.Height / rowHeight : 30;
sizeF = graphics.MeasureString(count.ToString(), view.Appearance.Row.Font);
return Convert.ToInt32(sizeF.Width) + 20;
int textWidth = TextRenderer.MeasureText(
count.ToString(),
view.Appearance.Row.Font,
Size.Empty,
TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
return textWidth + 20;
}
#endregion
}
+4 -1
View File
@@ -211,7 +211,10 @@ namespace Lskj.Control
private void btnClear_Click(object sender, EventArgs e)
{
try {
pictureEdit1.CreateGraphics().Clear(Color.White);
using (Graphics graphics = pictureEdit1.CreateGraphics())
{
graphics.Clear(Color.White);
}
_mousePath.Reset();
}
catch (Exception ex)
+109 -4
View File
@@ -63,6 +63,9 @@ namespace Lskj.Main.Model
private static CancellationTokenSource _sessionMonitorCancellation;
private static readonly List<Thread> SessionMonitorThreads =
new List<Thread>();
private static readonly object OpeningModuleSync = new object();
private static readonly HashSet<string> OpeningModuleKeys =
new HashSet<string>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// 默认下载地址
/// </summary>
@@ -285,6 +288,8 @@ namespace Lskj.Main.Model
/// Params">The URL parameters.</param>
public static void OpenModule(string menuId, string menuName, string dllName, string modelFlag, string urlParams)
{
string openingModuleKey = null;
bool ownsOpeningGate = false;
try
{
// 验证参数
@@ -293,6 +298,14 @@ namespace Lskj.Main.Model
MessageUtil.Show(ResourceKeys.NotFoundMenu);
return;
}
openingModuleKey = BuildOpeningModuleKey(menuId, dllName, modelFlag);
ownsOpeningGate = TryBeginOpenModule(openingModuleKey);
if (!ownsOpeningGate)
{
// 列数据源初始化期间可能会处理 WinForms 消息。
// 快速重复点击必须在页签注册前就被拦截,否则会构建多份重型控件树。
return;
}
// 验证权限
int purview = MainImpl.GetUserPurviewsByMenuId(menuId);
if (purview == 0)
@@ -416,8 +429,52 @@ namespace Lskj.Main.Model
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
finally
{
if (ownsOpeningGate)
{
EndOpenModule(openingModuleKey);
}
}
}
private static string BuildOpeningModuleKey(
string menuId,
string dllName,
string modelFlag)
{
return string.Join(
"|",
new[]
{
(menuId ?? string.Empty).Trim(),
(dllName ?? string.Empty).Trim(),
(modelFlag ?? string.Empty).Trim()
});
}
private static bool TryBeginOpenModule(string openingModuleKey)
{
lock (OpeningModuleSync)
{
if (OpeningModuleKeys.Contains(openingModuleKey))
{
return false;
}
OpeningModuleKeys.Add(openingModuleKey);
return true;
}
}
private static void EndOpenModule(string openingModuleKey)
{
lock (OpeningModuleSync)
{
OpeningModuleKeys.Remove(openingModuleKey);
}
}
/// <summary>
/// <para>说明:添加模块到tab中</para>
/// <para>创建人:龚宇超</para>
@@ -432,6 +489,10 @@ namespace Lskj.Main.Model
/// <param name="args">The arguments.</param>
public static void AddModuleToTab(DllModule module, string[] args)
{
string guid = null;
XtraTabPage tp = null;
Form form = null;
bool trackDogVerifiedModule = false;
try
{
bool isQuickLoad = (args[5] + "").Equals(SystemInfo.Instance.QuickMenuId);
@@ -441,8 +502,6 @@ namespace Lskj.Main.Model
// //QuickMenuForm.BringToFront();
// return;
//}
string guid = Guid.NewGuid().ToString();
XtraTabPage tp = new XtraTabPage();
if (SystemInfo.Instance.IsDogVerify)
{
if (!CheckPrivateTable())
@@ -497,7 +556,7 @@ namespace Lskj.Main.Model
}
else
{
StaticControl.DogVerifyModuleForms.Add(tp);
trackDogVerifiedModule = true;
}
}
else
@@ -532,12 +591,19 @@ namespace Lskj.Main.Model
return;
}
guid = Guid.NewGuid().ToString();
tp = new XtraTabPage();
if (trackDogVerifiedModule)
{
StaticControl.DogVerifyModuleForms.Add(tp);
}
ERPInfo.Instance.selectFormModleId = module.Id;
IForm iform = FormHelper.LoadDllForm(module.DllName, args);
// 菜单打开的模块默认最大化,界面FormState设置为Normal模式,否则会出现界面不是全屏,会显示默认阴影界面
//iform.SubForm.WindowState = _frmMain.WindowState;
iform.SubForm.WindowState = FormWindowState.Normal; ;
Form form = iform.SubForm; // 表示组成应用程序的用户界面的窗口或对话框。
form = iform.SubForm; // 表示组成应用程序的用户界面的窗口或对话框。
form.Tag = guid;
// 这个必须有不然会提示:"不能向tabControl中添加顶级控件"
form.TopLevel = isQuickLoad;
@@ -599,6 +665,7 @@ namespace Lskj.Main.Model
}
catch (Exception ex)
{
CleanupFailedModuleOpen(guid, tp, form);
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
LogHelper.Instance.WriteError(ex);
@@ -606,6 +673,44 @@ namespace Lskj.Main.Model
}
}
private static void CleanupFailedModuleOpen(
string guid,
XtraTabPage tabPage,
Form form)
{
try
{
if (!string.IsNullOrWhiteSpace(guid))
{
ModuleForms.Remove(guid);
}
if (tabPage != null)
{
StaticControl.DogVerifyModuleForms.Remove(tabPage);
if (TabMain != null && TabMain.TabPages.Contains(tabPage))
{
TabMain.TabPages.Remove(tabPage);
}
}
if (form != null && !form.IsDisposed)
{
form.Close();
form.Dispose();
}
if (tabPage != null && !tabPage.IsDisposed)
{
tabPage.Dispose();
}
}
catch (Exception cleanupException)
{
LogHelper.Instance.WriteError(cleanupException);
}
}
/// <summary>
/// 快速菜单关闭时,清除记录
/// </summary>
+55 -1
View File
@@ -206,7 +206,61 @@ namespace Lskj.PubModuleDetail
/// <param name="e"></param>
private void OnFrmMainDisposed(object sender, EventArgs e)
{
Model.DataCaches.Clear();
this.FormClosing -= OnClose;
this.Disposed -= OnFrmMainDisposed;
Dictionary<object, Hashtable> dataCaches =
Model != null ? Model.DataCaches : null;
if (dataCaches == null)
{
return;
}
DisposeCompletedCacheTasks(dataCaches);
dataCaches.Clear();
}
/// <summary>
/// 释放模块预加载缓存中已完成任务的等待句柄。
/// Task.Result 在等待时可能创建底层等待对象,仅清空字典
/// 不会立即释放这些句柄。
/// </summary>
private static void DisposeCompletedCacheTasks(
Dictionary<object, Hashtable> dataCaches)
{
HashSet<Task> tasks = new HashSet<Task>();
foreach (Hashtable cache in dataCaches.Values)
{
if (cache == null)
{
continue;
}
foreach (object value in cache.Values)
{
Task task = value as Task;
if (task != null)
{
tasks.Add(task);
}
}
}
foreach (Task task in tasks)
{
if (!task.IsCompleted)
{
continue;
}
try
{
task.Dispose();
}
catch (ObjectDisposedException)
{
}
}
}
}
}