fix(legacy): complete hosted module cleanup
This commit is contained in:
+262
-12
@@ -292,6 +292,85 @@ namespace Lskj.PubBill
|
||||
|
||||
private void ReleaseModuleEvents()
|
||||
{
|
||||
// BillModule 会给来源、明细以及明细的明细动态创建的 GridView 注册
|
||||
// 实例方法。DevExpress 的事件委托保存在 View 的 EventHandlerList 中,
|
||||
// 即使 View 已经脱离 GridControl,也会继续强引用 BillModule。关闭时
|
||||
// 只解除本模块注册的处理器,不 Dispose 共享的 GridControl/GridView。
|
||||
List<System.Windows.Forms.Control> moduleControls = new List<System.Windows.Forms.Control>();
|
||||
try
|
||||
{
|
||||
moduleControls.AddRange(EnumerateChildControls(this).ToList());
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("收集单据模块控件失败:" + exception);
|
||||
}
|
||||
|
||||
// Form.Close/Dispose 期间某些页签可能已经从 Controls 移除,
|
||||
// BillModuleModelDic 和页签 Tag 仍然保留这些动态控件的引用,
|
||||
// 因此一并加入快照,确保解绑覆盖所有来源表格。
|
||||
try
|
||||
{
|
||||
foreach (BillModuleModel moduleModel in BillModuleModelDic.Values.ToList())
|
||||
{
|
||||
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceControl as System.Windows.Forms.Control);
|
||||
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceDetailControl as System.Windows.Forms.Control);
|
||||
AddModuleControlSnapshot(moduleControls, moduleModel == null ? null : moduleModel.SourceDetailDetailControl as System.Windows.Forms.Control);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("收集单据来源控件失败:" + exception);
|
||||
}
|
||||
|
||||
foreach (System.Windows.Forms.Control control in moduleControls.ToList())
|
||||
{
|
||||
try
|
||||
{
|
||||
GridControlEx grid = control as GridControlEx;
|
||||
if (grid != null)
|
||||
ReleaseBillModuleGridEvents(grid);
|
||||
|
||||
TreeViewEx treeView = control as TreeViewEx;
|
||||
if (treeView != null)
|
||||
treeView.TreeNodeSelectAfter -= OnTreeNodeSelectAfter;
|
||||
|
||||
SplitContainerControl splitContainer = control as SplitContainerControl;
|
||||
if (splitContainer != null)
|
||||
{
|
||||
splitContainer.SplitterMoved -= OnTopSplitterMoved;
|
||||
splitContainer.SplitterMoved -= OnMainSplitterMoved;
|
||||
splitContainer.SplitterMoved -= OnDetailsSplitterMoved;
|
||||
splitContainer.SplitterMoved -= OnSpecialMainSplitterMoved;
|
||||
splitContainer.SplitterMoved -= OnSpecialLeftSplitterMoved;
|
||||
}
|
||||
|
||||
SimpleButton commonButton = control as SimpleButton;
|
||||
if (commonButton != null)
|
||||
commonButton.Click -= itemCommon_Click;
|
||||
|
||||
LabelImageEdit imageEdit = control as LabelImageEdit;
|
||||
if (imageEdit != null)
|
||||
{
|
||||
imageEdit.UploadEvent -= OnImageUploadEvent;
|
||||
imageEdit.DeleteEvent -= OnImageDeleteEvent;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("解除单据模块控件事件失败:" + exception);
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseBillModuleSearchEvents(moduleControls);
|
||||
ReleaseBillModuleBarEvents();
|
||||
|
||||
if (_imageEdit != null)
|
||||
{
|
||||
_imageEdit.UploadEvent -= OnImageUploadEvent;
|
||||
_imageEdit.DeleteEvent -= OnImageDeleteEvent;
|
||||
}
|
||||
|
||||
if (ScanCodeTextEdit != null)
|
||||
ScanCodeTextEdit.KeyDown -= Text_KeyDown;
|
||||
|
||||
@@ -299,18 +378,6 @@ namespace Lskj.PubBill
|
||||
{
|
||||
gcMain.OnAfterLinkCilk -= OnAfterLinkCilkCall;
|
||||
gcMain.OnAllAfterParseCallBack -= OnAllAfterParseCallBack;
|
||||
if (gcMain.GridControl != null)
|
||||
gcMain.GridControl.DataSourceChanged -= OnGcMainDataSourceChanged;
|
||||
if (gcMain.GridView != null)
|
||||
{
|
||||
gcMain.GridView.KeyDown -= OnToWithdraw;
|
||||
gcMain.GridView.ShowingEditor -= OnGridViewShowingEditor;
|
||||
gcMain.GridView.MouseDown -= GridView_MouseDown;
|
||||
gcMain.GridView.FocusedRowChanged -= GridView_FocusedRowChanged;
|
||||
gcMain.GridView.InitNewRow -= OnGridViewInitNewRow;
|
||||
gcMain.GridView.CellValueChanged -= OnGridViewCellValueChanged;
|
||||
gcMain.GridView.RowCellClick -= OngcMainRowCellClick;
|
||||
}
|
||||
}
|
||||
|
||||
if (tb_buttom != null)
|
||||
@@ -323,6 +390,189 @@ namespace Lskj.PubBill
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddModuleControlSnapshot(
|
||||
List<System.Windows.Forms.Control> target,
|
||||
System.Windows.Forms.Control control)
|
||||
{
|
||||
if (target == null || control == null)
|
||||
return;
|
||||
|
||||
foreach (System.Windows.Forms.Control item in EnumerateChildControls(control))
|
||||
{
|
||||
if (!target.Contains(item))
|
||||
target.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseBillModuleGridEvents(GridControlEx grid)
|
||||
{
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
grid.OnAfterLinkCilk -= OnAfterLinkCilkCall;
|
||||
grid.OnAllAfterParseCallBack -= OnAllAfterParseCallBack;
|
||||
if (grid.GridControl != null)
|
||||
{
|
||||
grid.GridControl.DataSourceChanged -= OnGcMainDataSourceChanged;
|
||||
grid.GridControl.ProcessGridKey -= OnGridControlKye;
|
||||
}
|
||||
|
||||
GridView view = grid.GridView;
|
||||
if (view != null)
|
||||
{
|
||||
view.DoubleClick -= OnGridViewDoubleClick;
|
||||
view.DoubleClick -= OnSourceGridViewDoubleClick;
|
||||
view.DoubleClick -= OnGridDetailDoubleClick;
|
||||
view.DoubleClick -= OnGridDetailDetailDoubleClick;
|
||||
view.RowCellClick -= OnGridViewRowCellClick;
|
||||
view.RowCellClick -= OngcMainRowCellClick;
|
||||
view.RowCellClick -= OnGridViewIsCheckClick;
|
||||
view.FocusedRowObjectChanged -= GridView_FocusedRowObjectChanged;
|
||||
view.FocusedRowChanged -= GridView_FocusedRowChanged;
|
||||
view.KeyDown -= OnToWithdraw;
|
||||
view.ShowingEditor -= OnGridViewShowingEditor;
|
||||
view.MouseDown -= GridView_MouseDown;
|
||||
view.InitNewRow -= OnGridViewInitNewRow;
|
||||
view.CellValueChanged -= OnGridViewCellValueChanged;
|
||||
view.CustomDrawCell -= GridView_CustomDrawCell;
|
||||
}
|
||||
|
||||
TreeGridControlEx treeGrid = grid as TreeGridControlEx;
|
||||
if (treeGrid != null && treeGrid.TreeListObj != null)
|
||||
{
|
||||
treeGrid.TreeListObj.FocusedNodeChanged -= OnTreeListObjFocusedNodeChanged;
|
||||
treeGrid.TreeListObj.MouseClick -= TreeListObj_MouseClick;
|
||||
treeGrid.TreeListObj.ShowingEditor -= OnGridViewShowingEditor;
|
||||
}
|
||||
|
||||
if (grid.gridViewRightMenu != null)
|
||||
{
|
||||
grid.gridViewRightMenu.OnBeforeHandleParamsCallback -= OnBeforeHandleParamsCallback;
|
||||
// SetGridRightMenus stores the module callback in the menu
|
||||
// object (not on GridView), so clear only this menu's callback
|
||||
// before the wrapper becomes unreachable.
|
||||
grid.gridViewRightMenu.SetRightCallback(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseBillModuleSearchEvents(
|
||||
IEnumerable<System.Windows.Forms.Control> moduleControls)
|
||||
{
|
||||
List<MyControl> searchControls = new List<MyControl>();
|
||||
List<MyControl> ownedSearchControls = new List<MyControl>();
|
||||
if (ControlObj != null)
|
||||
{
|
||||
searchControls.Add(ControlObj);
|
||||
ownedSearchControls.Add(ControlObj);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
IEnumerable<System.Windows.Forms.Control> controls = moduleControls == null
|
||||
? EnumerateChildControls(this)
|
||||
: moduleControls;
|
||||
foreach (System.Windows.Forms.Control control in controls)
|
||||
{
|
||||
XtraTabPage page = control as XtraTabPage;
|
||||
BillSourceUnionModel unionModel = page == null ? null : page.Tag as BillSourceUnionModel;
|
||||
if (unionModel == null)
|
||||
continue;
|
||||
|
||||
AddModuleSearchControl(searchControls, unionModel.SearchObj);
|
||||
AddModuleSearchControl(ownedSearchControls, unionModel.SearchObj);
|
||||
ModuleGridEx detailModule = unionModel.GridDetailModuleGridEx;
|
||||
if (detailModule != null)
|
||||
{
|
||||
AddModuleSearchControl(searchControls, detailModule.SearchObj);
|
||||
AddModuleSearchControl(ownedSearchControls, detailModule.SearchObj);
|
||||
// ParentControlEx/ParentControlObj/_leftGridSearchObj can
|
||||
// belong to another open module. They only need this
|
||||
// module's callbacks removed; never Dispose them here.
|
||||
AddModuleSearchControl(searchControls, detailModule.ParentControlEx);
|
||||
AddModuleSearchControl(searchControls, detailModule.ParentControlObj);
|
||||
AddModuleSearchControl(searchControls, detailModule._leftGridSearchObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("收集单据查询控件失败:" + exception);
|
||||
}
|
||||
|
||||
foreach (MyControl searchControl in searchControls.ToList())
|
||||
{
|
||||
if (searchControl == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
searchControl.OnSearchBeforeCallBack -= OnSearchBefore;
|
||||
searchControl.OnSearchAfterCallBack -= OnSearchAfterd;
|
||||
searchControl.OnDataSourceBindCallBack -= OnFirstPageDataSourceBindCallBack;
|
||||
searchControl.OnDataSourceBindCallBack -= SearchControl_OnDataSourceBindCallBack;
|
||||
searchControl.OnDataSourceBindCallBack -= OnPageDataSourceBindCallBack;
|
||||
searchControl.OpenDocumentSource -= OpenTheSourcePopup;
|
||||
searchControl.OnSourceRefrshCallBack -= OnRefreshBillSource;
|
||||
searchControl.OnDataFileRefrshCallBack -= OnDataFileRefrshFile;
|
||||
searchControl.OnDataSourceBindCallBack -= OnInitializeHeaderCallBack;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("解除单据查询事件失败:" + exception);
|
||||
}
|
||||
}
|
||||
|
||||
// MyControl 不是 WinForms Control,不会随页签自动进入 Dispose
|
||||
// 链。它内部可能持有 WinForms Timer、弹出菜单和查询控件引用;
|
||||
// 只释放本模块创建的对象,外部传入的父级查询控件保持不动。
|
||||
foreach (MyControl searchControl in ownedSearchControls.ToList())
|
||||
{
|
||||
try
|
||||
{
|
||||
searchControl.Dispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.WriteLine("释放单据查询控件失败:" + exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddModuleSearchControl(List<MyControl> target, MyControl control)
|
||||
{
|
||||
if (target != null && control != null && !target.Contains(control))
|
||||
target.Add(control);
|
||||
}
|
||||
|
||||
private void ReleaseBillModuleBarEvents()
|
||||
{
|
||||
if (itemCommonList != null)
|
||||
{
|
||||
foreach (SimpleButton button in itemCommonList.ToList())
|
||||
if (button != null)
|
||||
button.Click -= itemCommon_Click;
|
||||
}
|
||||
|
||||
if (barManager1 == null || barManager1.Items == null)
|
||||
return;
|
||||
|
||||
foreach (BarItem item in barManager1.Items)
|
||||
{
|
||||
BarButtonItem button = item as BarButtonItem;
|
||||
if (button == null)
|
||||
continue;
|
||||
|
||||
button.ItemClick -= OnCopyMasterItemClick;
|
||||
button.ItemClick -= OnCopyAllItemClick;
|
||||
button.ItemClick -= OnExportItemClick;
|
||||
button.ItemClick -= OnBtnFPNewClick;
|
||||
button.ItemClick -= OnImportItemClick;
|
||||
button.ItemClick -= OnImportUpdateItemClick;
|
||||
button.ItemClick -= OnPrintItemClick;
|
||||
button.ItemClick -= OnCommonItemClick;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseModuleDataSources()
|
||||
{
|
||||
foreach (System.Windows.Forms.Control control in EnumerateChildControls(this).ToList())
|
||||
|
||||
Reference in New Issue
Block a user