fix(legacy): complete hosted module cleanup

This commit is contained in:
2026-08-29 20:34:39 +08:00
parent 176952d52c
commit 9f5f548dea
15 changed files with 704 additions and 422 deletions
+121 -51
View File
@@ -435,6 +435,9 @@ namespace Lskj.Control
/// </summary>
public MyControl SearchObj { get; private set; }
private bool mModuleResourcesReleased;
// GridControlObj 可能由其他控件传入(例如左右明细表)。只有本控件
// 自己创建的表格才属于本控件,外部表格的生命周期仍由其父容器负责。
private bool _ownsGridControl = true;
/// <summary>
/// 左查询条件
/// </summary>
@@ -446,7 +449,52 @@ namespace Lskj.Control
public GridControlEx GridControlObj
{
get { return this.gcMain; }
set { this.gcMain = value; }
set { AssignGridControl(value, false); }
}
private void AssignGridControl(GridControlEx value, bool ownsGridControl)
{
GridControlEx previous = this.gcMain;
bool previousOwned = _ownsGridControl;
if (ReferenceEquals(previous, value))
{
_ownsGridControl = ownsGridControl;
return;
}
this.gcMain = value;
_ownsGridControl = ownsGridControl;
// 旧表格可能已经因为 Controls.Clear() 脱离父容器,此时 Parent 为空,
// 但它仍然属于本模块,不能仅靠解除父引用等待回收。只释放本控件
// 自己创建的实例,外部传入的表格仍由其真实拥有者负责生命周期。
if (previous != null && previousOwned)
{
try
{
if (previous.Parent != null)
{
previous.Parent.Controls.Remove(previous);
}
}
catch
{
// 父容器可能已进入 Dispose,继续释放旧表格本身。
}
try
{
if (!previous.IsDisposed)
{
previous.Dispose();
}
}
catch
{
// 控件处于部分销毁状态时不能阻止新表格完成替换。
}
}
}
/// <summary>
/// 底部多标签控件
@@ -1018,7 +1066,9 @@ namespace Lskj.Control
{
// 创建 多表头,树表格
this.panelControl1.Controls.Clear();
this.gcMain = new TreeBandedGridControlEx() { Expansion = SysModel.TreeTableExpand };
AssignGridControl(
new TreeBandedGridControlEx() { Expansion = SysModel.TreeTableExpand },
true);
this.gcMain.Model = this.Model;
this.gcMain.SysModel = this.SysModel;
(this.gcMain as TreeBandedGridControlEx).moduleModel = this.SysModel;
@@ -1045,7 +1095,7 @@ namespace Lskj.Control
if (this.gcMain.gridControl.Tag is PanelControl) panel = this.gcMain.gridControl.Tag as PanelControl;
this.panelControl1.Controls.Clear();
this.gcMain = new BandedGridControlEx();
AssignGridControl(new BandedGridControlEx(), true);
(this.gcMain as BandedGridControlEx).moduleModel = this.SysModel;
this.gcMain.Model = this.Model;
this.gcMain.SysModel = this.SysModel;
@@ -1062,7 +1112,9 @@ namespace Lskj.Control
{
// 创建树表格
this.panelControl1.Controls.Clear();
this.gcMain = new TreeGridControlEx() { Expansion = SysModel.TreeTableExpand };
AssignGridControl(
new TreeGridControlEx() { Expansion = SysModel.TreeTableExpand },
true);
this.gcMain.Model = this.Model;
this.gcMain.SysModel = this.SysModel;
this.gcMain.Dock = DockStyle.Fill;
@@ -3351,8 +3403,11 @@ namespace Lskj.Control
string[] menuArgs = new string[] { "", "", url };
string[] args = defaultArgs.Concat(menuArgs).ToArray();
IForm form = FormHelper.LoadDllForm(ResourceDynamic.PubBrower, args);
form.SubForm.WindowState = FormWindowState.Maximized;
DialogResult result = form.SubForm.ShowDialog();
using (Form subForm = form.SubForm)
{
subForm.WindowState = FormWindowState.Maximized;
subForm.ShowDialog();
}
}
else
{
@@ -3361,14 +3416,17 @@ namespace Lskj.Control
string[] menuArgs = { "", canUpdate ? "0" : "1", selectRow[_parmaryKey] + "" };
string[] args = defaultArgs.Concat(menuArgs).ToArray();
IForm form = FormHelper.LoadDllForm(ResourceDynamic.PubAdd, args);
DialogResult result = form.SubForm.ShowDialog();
//RefreshColumn();
if (result == DialogResult.OK)
using (Form subForm = form.SubForm)
{
this.SearchObj.SearchLastGrid();
if (OnSaveGridCallBack != null)
DialogResult result = subForm.ShowDialog();
//RefreshColumn();
if (result == DialogResult.OK)
{
this.OnSaveGridCallBack(null, null);
this.SearchObj.SearchLastGrid();
if (OnSaveGridCallBack != null)
{
this.OnSaveGridCallBack(null, null);
}
}
}
@@ -3785,63 +3843,75 @@ namespace Lskj.Control
searchObj.Dispose();
}
GridControlEx grid = gcMain;
try
{
if (gcMain != null)
if (grid != null)
{
if (ReferenceEquals(StaticControl.RightMenuGridView, gcMain.GridView))
if (ReferenceEquals(StaticControl.RightMenuGridView, grid.GridView))
{
StaticControl.RightMenuGridView = null;
}
if (gcMain.GridView != null)
if (grid.GridView != null)
{
gcMain.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
gcMain.GridView.ShowingEditor -= OnGridViewShowingEditor;
gcMain.GridView.DoubleClick -= OnGridViewDoubleClick;
gcMain.GridView.MouseDown -= OnGridViewMouseDown;
gcMain.GridView.MouseDown -= OnGridMouseDown;
gcMain.GridView.MouseMove -= OnGridMouseMove;
gcMain.GridView.MouseUp -= OnGridMouseUp;
grid.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
grid.GridView.ShowingEditor -= OnGridViewShowingEditor;
grid.GridView.DoubleClick -= OnGridViewDoubleClick;
grid.GridView.MouseDown -= OnGridViewMouseDown;
grid.GridView.MouseDown -= OnGridMouseDown;
grid.GridView.MouseMove -= OnGridMouseMove;
grid.GridView.MouseUp -= OnGridMouseUp;
}
if (gcMain.CustomGroupBandEx != null)
if (grid.CustomGroupBandEx != null)
{
gcMain.CustomGroupBandEx.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
gcMain.CustomGroupBandEx.GridView.ShowingEditor -= OnGridViewShowingEditor;
grid.CustomGroupBandEx.GridView.FocusedRowObjectChanged -= OnGridViewFocusedRowObjectChanged;
grid.CustomGroupBandEx.GridView.ShowingEditor -= OnGridViewShowingEditor;
}
if (gcMain.ParentControl != null &&
ReferenceEquals(gcMain.ParentControl, searchObj))
if (grid.ParentControl != null &&
ReferenceEquals(grid.ParentControl, searchObj))
{
gcMain.ParentControl = null;
grid.ParentControl = null;
}
gcMain.Model = null;
gcMain.SysModel = null;
try
{
gcMain.ReleaseResourcesForDispose();
}
catch
{
// Resource cleanup must not block the module close path.
}
try
{
if (!gcMain.IsDisposed)
{
gcMain.Dispose();
}
}
catch
{
// A partially disposed grid must not block the module close path.
}
gcMain = null;
}
}
catch
{
// A partially disposed DevExpress view must not stop module cleanup.
}
finally
{
// 自有表格的生命周期由本模块负责。先从父容器移除,再显式释放,
// 防止调用方此前执行 Controls.Clear() 后留下孤立 GridControlEx。
bool ownsGrid = _ownsGridControl;
gcMain = null;
_ownsGridControl = false;
if (ownsGrid && grid != null)
{
try
{
if (grid.Parent != null)
{
grid.Parent.Controls.Remove(grid);
}
}
catch
{
// 父容器可能已进入 Dispose,继续释放表格本身。
}
try
{
if (!grid.IsDisposed)
{
grid.Dispose();
}
}
catch
{
// 部分销毁的 DevExpress 控件不能阻止模块其余资源清理。
}
}
}
try
{