diff --git a/插件库/Lskj.BaseAccraditation/FrmBaseAccraditation.cs b/插件库/Lskj.BaseAccraditation/FrmBaseAccraditation.cs index 531738a..34f0b80 100644 --- a/插件库/Lskj.BaseAccraditation/FrmBaseAccraditation.cs +++ b/插件库/Lskj.BaseAccraditation/FrmBaseAccraditation.cs @@ -2077,15 +2077,15 @@ namespace Lskj.BaseAccraditation if (refreshThePage != null) { - refreshThePage("审核成功", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("审核成功", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2093,13 +2093,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2261,15 +2261,15 @@ namespace Lskj.BaseAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("审核成功", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("审核成功", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2277,13 +2277,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2391,15 +2391,15 @@ namespace Lskj.BaseAccraditation if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2407,13 +2407,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2451,15 +2451,15 @@ namespace Lskj.BaseAccraditation if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2467,13 +2467,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2527,15 +2527,15 @@ namespace Lskj.BaseAccraditation if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2543,13 +2543,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2609,15 +2609,15 @@ namespace Lskj.BaseAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2625,13 +2625,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2669,15 +2669,15 @@ namespace Lskj.BaseAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2685,13 +2685,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } diff --git a/插件库/Lskj.BaseAccraditation/FrmMain.cs b/插件库/Lskj.BaseAccraditation/FrmMain.cs index 7019d52..633ec4d 100644 --- a/插件库/Lskj.BaseAccraditation/FrmMain.cs +++ b/插件库/Lskj.BaseAccraditation/FrmMain.cs @@ -317,7 +317,7 @@ namespace Lskj.BaseAccraditation if (SystemInfo.Instance.PageOpen) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { int interceptionLocation = tablepage.Text.Length - frmbaseAccradit.SysModel.PrimaryValue.Length - 1; if (interceptionLocation > 0 && tablepage.Text.Length > frmbaseAccradit.SysModel.PrimaryValue.Length) @@ -326,7 +326,7 @@ namespace Lskj.BaseAccraditation if (documentNo.Equals(frmbaseAccradit.SysModel.PrimaryValue)) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return; } } @@ -336,7 +336,7 @@ namespace Lskj.BaseAccraditation DllName = "", Id = SysModel.ModuleId + "", Name = SysModel.FormText, - BeforePage = ERPInfo.Instance.PageControl.SelectedTabPage, + BeforePage = ERPInfo.Instance.CurrentModulePage, ModuleForm = frmbaseAccradit }; frmbaseAccradit.refreshThePage += new FrmBaseAccraditation.RefreshThePage(refreshThePage); @@ -353,8 +353,8 @@ namespace Lskj.BaseAccraditation tp.Controls.Add(frmbaseAccradit); tp.ShowCloseButton = DefaultBoolean.True; tp.Dock = DockStyle.Fill; - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; frmbaseAccradit.Opacity = 0; frmbaseAccradit.SetFormSize(); frmbaseAccradit.Show(); @@ -440,7 +440,7 @@ namespace Lskj.BaseAccraditation if (SystemInfo.Instance.PageOpen) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { int interceptionLocation = tablepage.Text.Length - frmbaseAccradit.SysModel.PrimaryValue.Length - 1; if (interceptionLocation > 0 && tablepage.Text.Length > frmbaseAccradit.SysModel.PrimaryValue.Length) @@ -449,7 +449,7 @@ namespace Lskj.BaseAccraditation if (documentNo.Equals(frmbaseAccradit.SysModel.PrimaryValue)) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return; } } @@ -459,7 +459,7 @@ namespace Lskj.BaseAccraditation DllName = "", Id = SysModel.ModuleId + "", Name = SysModel.FormText, - BeforePage = ERPInfo.Instance.PageControl.SelectedTabPage, + BeforePage = ERPInfo.Instance.CurrentModulePage, ModuleForm = frmbaseAccradit }; frmbaseAccradit.refreshThePage += new FrmBaseAccraditation.RefreshThePage(refreshThePage); @@ -477,8 +477,8 @@ namespace Lskj.BaseAccraditation tp.Controls.Add(frmbaseAccradit); tp.ShowCloseButton = DefaultBoolean.True; tp.Dock = DockStyle.Fill; - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; frmbaseAccradit.Opacity = 0; frmbaseAccradit.SetFormSize(); frmbaseAccradit.Show(); @@ -521,13 +521,13 @@ namespace Lskj.BaseAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); } } } diff --git a/插件库/Lskj.Control/BandedGridControlEx.cs b/插件库/Lskj.Control/BandedGridControlEx.cs index 8c23b7e..13fc52c 100644 --- a/插件库/Lskj.Control/BandedGridControlEx.cs +++ b/插件库/Lskj.Control/BandedGridControlEx.cs @@ -2524,7 +2524,7 @@ namespace Lskj.Control DllName = "", Id = this.Model.ModuleCode, Name = this.Model.FormText, - BeforePage = ERPInfo.Instance.PageControl.SelectedTabPage + BeforePage = ERPInfo.Instance.CurrentModulePage }; module.ModuleForm = frmGridSift; string guid = Guid.NewGuid().ToString(); @@ -2541,8 +2541,8 @@ namespace Lskj.Control tp.Controls.Add(frmGridSift); tp.ShowCloseButton = DefaultBoolean.True; tp.Dock = DockStyle.Fill; - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; ERPInfo.Instance.ModuleForms.Add(guid, module); frmGridSift.Show(); } diff --git a/插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs b/插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs index cc4bcee..5f6ff0c 100644 --- a/插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs +++ b/插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs @@ -171,12 +171,12 @@ namespace Lskj.Control.BrowserSetting dllName = MainImpl.GetDefaultValue(dllName); if (SystemInfo.Instance.SoftOpenMode) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Text == menuName) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return; } } @@ -302,8 +302,8 @@ namespace Lskj.Control.BrowserSetting DialogResult dialogResult = mcpex.ShowDialog(); } } - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; ERPInfo.Instance.ModuleForms.Add(guid, module); } diff --git a/插件库/Lskj.Control/Model/GridExtend.cs b/插件库/Lskj.Control/Model/GridExtend.cs index c459b97..a7031ee 100644 --- a/插件库/Lskj.Control/Model/GridExtend.cs +++ b/插件库/Lskj.Control/Model/GridExtend.cs @@ -4126,7 +4126,7 @@ namespace Lskj.Control.Model // 添加内容 if (i == 0) { - string guid = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string guid = ERPInfo.Instance.CurrentModulePage.Tag + ""; DllModule model = ERPInfo.Instance.ModuleForms[guid]; cell.SetCellValue(model.Name); } diff --git a/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs b/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs index 2757d80..57d1743 100644 --- a/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs +++ b/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs @@ -1228,7 +1228,7 @@ namespace Lskj.Control.Model paramList[12], paramList[13]//固定添加行数据json字符串 }; - XtraTabPage xtraTab = ERPInfo.Instance.PageControl != null ? ERPInfo.Instance.PageControl.SelectedTabPage : null; + XtraTabPage xtraTab = ERPInfo.Instance.CurrentModulePage != null ? ERPInfo.Instance.CurrentModulePage : null; DllModule module = new DllModule { DllName = ReplaceDllFileName(dllName), @@ -1240,12 +1240,12 @@ namespace Lskj.Control.Model { if (SystemInfo.Instance.SoftOpenMode) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Text == model.MenuName) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return false; } } @@ -1408,8 +1408,8 @@ namespace Lskj.Control.Model { tp.Disposed += new EventHandler(OnTp_Disposed); } - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; if (isPrivateDll) { StaticControl.DogVerifyModuleForms.Add(tp); diff --git a/插件库/Lskj.Control/Model/StaticBandedControl.cs b/插件库/Lskj.Control/Model/StaticBandedControl.cs index e1de379..da8b13b 100644 --- a/插件库/Lskj.Control/Model/StaticBandedControl.cs +++ b/插件库/Lskj.Control/Model/StaticBandedControl.cs @@ -15,11 +15,25 @@ namespace Lskj.Control.Model public static class StaticBandedControl { public static void ReleaseModuleReferences(WinFormsControl moduleRoot, XtraTabPage modulePage, string moduleCode) + { + List moduleControls = CollectModuleControls(moduleRoot, modulePage); + ReleaseModuleReferences(moduleControls, modulePage, moduleCode); + } + + internal static void ReleaseModuleReferences( + IEnumerable moduleControls, + XtraTabPage modulePage, + string moduleCode) { try { - List bandedViews = CollectBandedGridViews(moduleRoot); - List targetViews = CollectTargetGridViews(moduleRoot); + List controls = new List(); + if (moduleControls != null) + foreach (WinFormsControl control in moduleControls) + if (control != null && !ContainsControl(controls, control)) + controls.Add(control); + List bandedViews = CollectBandedGridViews(controls); + List targetViews = CollectTargetGridViews(controls); foreach (BandedGridView view in bandedViews) BandedGridDragGrid.DisposeRegistrations( BandedGridViewDragGridDic, @@ -32,14 +46,10 @@ namespace Lskj.Control.Model BandedTargetViewDragGridDic, null, view); - if (SourceDragBandedGridView != null && - (bandedViews.Contains(SourceDragBandedGridView) || - (SourceDragBandedGridView.GridControl != null && SourceDragBandedGridView.GridControl.IsDisposed))) + if (ContainsBandedGridView(bandedViews, SourceDragBandedGridView)) SourceDragBandedGridView = null; - RemoveConditionPanels(moduleCode); - while (modulePage != null && DogVerifyModuleForms.Remove(modulePage)) - { - } + RemoveConditionPanels(moduleCode, controls); + RemoveProtectedReferences(controls, modulePage); } catch (Exception exception) { @@ -47,36 +57,116 @@ namespace Lskj.Control.Model } } - private static List CollectBandedGridViews(WinFormsControl root) + private static List CollectModuleControls( + WinFormsControl moduleRoot, + XtraTabPage modulePage) + { + List result = new List(); + AddModuleControls(result, moduleRoot); + if (!ReferenceEquals(moduleRoot, modulePage)) + AddModuleControls(result, modulePage); + return result; + } + + private static void AddModuleControls( + List target, + WinFormsControl root) + { + if (root == null) + return; + foreach (WinFormsControl control in EnumerateControls(root)) + if (!ContainsControl(target, control)) + target.Add(control); + } + + private static List CollectBandedGridViews( + IEnumerable controls) { List result = new List(); - if (root == null) + if (controls == null) return result; - foreach (WinFormsControl control in EnumerateControls(root)) + foreach (WinFormsControl control in controls) { DevExpress.XtraGrid.GridControl grid = control as DevExpress.XtraGrid.GridControl; - BandedGridView view = grid == null ? null : grid.MainView as BandedGridView; - if (view != null && !result.Contains(view)) - result.Add(view); + if (grid == null) + continue; + try + { + AddBandedGridView(result, grid.MainView as BandedGridView); + foreach (DevExpress.XtraGrid.Views.Base.BaseView baseView in grid.ViewCollection) + AddBandedGridView(result, baseView as BandedGridView); + } + catch (Exception exception) + { + System.Diagnostics.Debug.WriteLine("读取旧 Banded 表格视图失败:" + exception); + } } return result; } - private static List CollectTargetGridViews(WinFormsControl root) + private static void AddBandedGridView( + List target, + BandedGridView view) + { + if (view != null && !ContainsBandedGridView(target, view)) + target.Add(view); + } + + private static bool ContainsBandedGridView( + IEnumerable gridViews, + BandedGridView value) + { + if (gridViews == null || value == null) + return false; + foreach (BandedGridView gridView in gridViews) + if (ReferenceEquals(gridView, value)) + return true; + return false; + } + + private static List CollectTargetGridViews( + IEnumerable controls) { List result = new List(); - if (root == null) + if (controls == null) return result; - foreach (WinFormsControl control in EnumerateControls(root)) + foreach (WinFormsControl control in controls) { DevExpress.XtraGrid.GridControl grid = control as DevExpress.XtraGrid.GridControl; - GridView view = grid == null ? null : grid.MainView as GridView; - if (view != null && !result.Contains(view)) - result.Add(view); + if (grid == null) + continue; + try + { + AddGridView(result, grid.MainView as GridView); + foreach (DevExpress.XtraGrid.Views.Base.BaseView baseView in grid.ViewCollection) + AddGridView(result, baseView as GridView); + } + catch (Exception exception) + { + System.Diagnostics.Debug.WriteLine("读取旧 Banded 目标表格视图失败:" + exception); + } } return result; } + private static void AddGridView(List target, GridView view) + { + if (view != null && !ContainsGridView(target, view)) + target.Add(view); + } + + private static bool ContainsGridView( + IEnumerable gridViews, + GridView value) + { + if (gridViews == null || value == null) + return false; + foreach (GridView gridView in gridViews) + if (ReferenceEquals(gridView, value)) + return true; + return false; + } + private static IEnumerable EnumerateControls(WinFormsControl root) { yield return root; @@ -85,16 +175,67 @@ namespace Lskj.Control.Model yield return nested; } - private static void RemoveConditionPanels(string moduleCode) + private static void RemoveConditionPanels( + string moduleCode, + IEnumerable moduleControls) { foreach (string key in ConditionsPanelDic.Keys.ToList()) { ModuleConditionsPanelEx panel; - if (string.Equals(key, moduleCode, StringComparison.OrdinalIgnoreCase) || - !ConditionsPanelDic.TryGetValue(key, out panel) || panel == null || panel.IsDisposed) + if (!ConditionsPanelDic.TryGetValue(key, out panel) || panel == null || panel.IsDisposed) + { + ConditionsPanelDic.Remove(key); + continue; + } + + if (string.Equals(key, moduleCode, StringComparison.OrdinalIgnoreCase) && + IsConditionPanelOwnedByModule(panel, moduleControls)) ConditionsPanelDic.Remove(key); } } + + private static bool IsConditionPanelOwnedByModule( + ModuleConditionsPanelEx panel, + IEnumerable moduleControls) + { + if (panel == null) + return false; + if (ContainsControl(moduleControls, panel) || ContainsControl(moduleControls, panel.Owner)) + return true; + + MyControl parentControl = panel.ParentControlObj; + return parentControl != null && + parentControl.MainGridEx != null && + ContainsControl(moduleControls, parentControl.MainGridEx); + } + + private static void RemoveProtectedReferences( + IEnumerable moduleControls, + XtraTabPage modulePage) + { + while (modulePage != null && DogVerifyModuleForms.Remove(modulePage)) + { + } + foreach (XtraTabPage item in DogVerifyModuleForms.ToList()) + if (item == null || item.IsDisposed || ContainsControl(moduleControls, item)) + DogVerifyModuleForms.Remove(item); + foreach (IForm item in DogVerifyNoPageForms.ToList()) + if (item == null || item.SubForm == null || item.SubForm.IsDisposed || + ContainsControl(moduleControls, item.SubForm)) + DogVerifyNoPageForms.Remove(item); + } + + private static bool ContainsControl( + IEnumerable moduleControls, + WinFormsControl value) + { + if (moduleControls == null || value == null) + return false; + foreach (WinFormsControl control in moduleControls) + if (ReferenceEquals(control, value)) + return true; + return false; + } /// /// 记录当前U盾权限窗口 /// diff --git a/插件库/Lskj.Control/ModuleGridEx.cs b/插件库/Lskj.Control/ModuleGridEx.cs index e13d012..f4489be 100644 --- a/插件库/Lskj.Control/ModuleGridEx.cs +++ b/插件库/Lskj.Control/ModuleGridEx.cs @@ -435,6 +435,9 @@ namespace Lskj.Control /// public MyControl SearchObj { get; private set; } private bool mModuleResourcesReleased; + // GridControlObj 可能由其他控件传入(例如左右明细表)。只有本控件 + // 自己创建的表格才属于本控件,外部表格的生命周期仍由其父容器负责。 + private bool _ownsGridControl = true; /// /// 左查询条件 /// @@ -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 + { + // 控件处于部分销毁状态时不能阻止新表格完成替换。 + } + } } /// /// 底部多标签控件 @@ -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 { diff --git a/插件库/Lskj.Control/ModulePanelEx.Designer.cs b/插件库/Lskj.Control/ModulePanelEx.Designer.cs index 18e07ad..6e2d41f 100644 --- a/插件库/Lskj.Control/ModulePanelEx.Designer.cs +++ b/插件库/Lskj.Control/ModulePanelEx.Designer.cs @@ -34,14 +34,15 @@ namespace Lskj.Control /// private void InitializeComponent() { - this.pm_print = new DevExpress.XtraBars.PopupMenu(); - this.barManager1 = new DevExpress.XtraBars.BarManager(); + this.components = new System.ComponentModel.Container(); + this.pm_print = new DevExpress.XtraBars.PopupMenu(this.components); + this.barManager1 = new DevExpress.XtraBars.BarManager(this.components); 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.pm_common = new DevExpress.XtraBars.PopupMenu(); - this.pm_oper = new DevExpress.XtraBars.PopupMenu(); + this.pm_common = new DevExpress.XtraBars.PopupMenu(this.components); + this.pm_oper = new DevExpress.XtraBars.PopupMenu(this.components); this.panel1 = new System.Windows.Forms.Panel(); this.scc_container = new DevExpress.XtraEditors.SplitContainerControl(); this.panel_Main = new System.Windows.Forms.Panel(); diff --git a/插件库/Lskj.PubAccraditation/FrmAccraditation.cs b/插件库/Lskj.PubAccraditation/FrmAccraditation.cs index b05b321..13b5206 100644 --- a/插件库/Lskj.PubAccraditation/FrmAccraditation.cs +++ b/插件库/Lskj.PubAccraditation/FrmAccraditation.cs @@ -2627,27 +2627,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2694,14 +2694,14 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("审核成功", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("审核成功", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2709,13 +2709,13 @@ namespace Lskj.PubAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2773,27 +2773,27 @@ namespace Lskj.PubAccraditation //this.Close(); if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -2879,14 +2879,14 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("审核成功", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("审核成功", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { @@ -2894,13 +2894,13 @@ namespace Lskj.PubAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -3218,27 +3218,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -3278,27 +3278,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -3352,27 +3352,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -3432,27 +3432,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } @@ -3517,27 +3517,27 @@ namespace Lskj.PubAccraditation this.DialogResult = DialogResult.OK; if (refreshThePage != null) { - refreshThePage("", ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""); + refreshThePage("", ERPInfo.Instance.CurrentModulePage.Tag + ""); } else { //上一次点开page 当前打开page删除后要选中的page - if (ERPInfo.Instance.PageControl != null) + if (ERPInfo.Instance.HasModulePageSurface) { - string id = ERPInfo.Instance.PageControl.SelectedTabPage.Tag + ""; + string id = ERPInfo.Instance.CurrentModulePage.Tag + ""; XtraTabPage beforePage = ERPInfo.Instance.ModuleForms[id].BeforePage; if (beforePage != null) { //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); removePage.Dispose(); } } diff --git a/插件库/Lskj.PubAccraditation/FrmMain.cs b/插件库/Lskj.PubAccraditation/FrmMain.cs index b9562eb..48a57b6 100644 --- a/插件库/Lskj.PubAccraditation/FrmMain.cs +++ b/插件库/Lskj.PubAccraditation/FrmMain.cs @@ -259,7 +259,7 @@ namespace Lskj.PubAccraditation if (SystemInfo.Instance.PageOpen) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { int interceptionLocation = tablepage.Text.Length - frm.SysModel.BillDocumentId.Length - 1; if (interceptionLocation > 0 && tablepage.Text.Length > frm.SysModel.BillDocumentId.Length) @@ -269,7 +269,7 @@ namespace Lskj.PubAccraditation if (documentNo.Equals(frm.SysModel.BillDocumentId)) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return; } } @@ -279,7 +279,7 @@ namespace Lskj.PubAccraditation DllName = "", Id = SysModel.ModuleId + "", Name = SysModel.FormText, - BeforePage = ERPInfo.Instance.PageControl.SelectedTabPage, + BeforePage = ERPInfo.Instance.CurrentModulePage, ModuleForm = frm }; frm.refreshThePage += new FrmAccraditation.RefreshThePage(refreshThePage); @@ -295,8 +295,8 @@ namespace Lskj.PubAccraditation tp.Controls.Add(frm); tp.ShowCloseButton = DefaultBoolean.True; tp.Dock = DockStyle.Fill; - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; frm.Show(); tp.Text = frm.Text; ERPInfo.Instance.ModuleForms.Add(guid, module); @@ -345,7 +345,7 @@ namespace Lskj.PubAccraditation if (SystemInfo.Instance.PageOpen) { - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { int interceptionLocation = tablepage.Text.Length - frm.SysModel.BillDocumentId.Length - 1; if (interceptionLocation > 0 && tablepage.Text.Length > frm.SysModel.BillDocumentId.Length) @@ -355,7 +355,7 @@ namespace Lskj.PubAccraditation if (documentNo.Equals(frm.SysModel.BillDocumentId)) { MessageUtil.Show("已设置不能打开多个相同模块!"); - ERPInfo.Instance.PageControl.SelectedTabPage = tablepage; + ERPInfo.Instance.CurrentModulePage = tablepage; return; } } @@ -365,7 +365,7 @@ namespace Lskj.PubAccraditation DllName = "", Id = SysModel.ModuleId + "", Name = SysModel.FormText, - BeforePage = ERPInfo.Instance.PageControl.SelectedTabPage, + BeforePage = ERPInfo.Instance.CurrentModulePage, ModuleForm = frm }; frm.refreshThePage += new FrmAccraditation.RefreshThePage(refreshThePage); @@ -382,8 +382,8 @@ namespace Lskj.PubAccraditation tp.Controls.Add(frm); tp.ShowCloseButton = DefaultBoolean.True; tp.Dock = DockStyle.Fill; - ERPInfo.Instance.PageControl.TabPages.Add(tp); - ERPInfo.Instance.PageControl.SelectedTabPage = tp; + ERPInfo.Instance.AddModulePage(tp); + ERPInfo.Instance.CurrentModulePage = tp; frm.Show(); tp.Text = frm.Text; ERPInfo.Instance.ModuleForms.Add(guid, module); @@ -422,13 +422,13 @@ namespace Lskj.PubAccraditation //要删除的page XtraTabPage removePage = new XtraTabPage(); ERPInfo.Instance.ModuleForms.Remove(id); - foreach (XtraTabPage tablepage in ERPInfo.Instance.PageControl.TabPages) + foreach (XtraTabPage tablepage in ERPInfo.Instance.ModulePages) { if (tablepage.Tag == null) continue; if (tablepage.Tag.ToString().Equals(id)) removePage = tablepage; - if (tablepage == beforePage) ERPInfo.Instance.PageControl.SelectedTabPage = beforePage; + if (tablepage == beforePage) ERPInfo.Instance.CurrentModulePage = beforePage; } - ERPInfo.Instance.PageControl.TabPages.Remove(removePage); + ERPInfo.Instance.RemoveModulePage(removePage); } } diff --git a/插件库/Lskj.PubBill/BillModule.cs b/插件库/Lskj.PubBill/BillModule.cs index a894667..dc828e1 100644 --- a/插件库/Lskj.PubBill/BillModule.cs +++ b/插件库/Lskj.PubBill/BillModule.cs @@ -292,6 +292,85 @@ namespace Lskj.PubBill private void ReleaseModuleEvents() { + // BillModule 会给来源、明细以及明细的明细动态创建的 GridView 注册 + // 实例方法。DevExpress 的事件委托保存在 View 的 EventHandlerList 中, + // 即使 View 已经脱离 GridControl,也会继续强引用 BillModule。关闭时 + // 只解除本模块注册的处理器,不 Dispose 共享的 GridControl/GridView。 + List moduleControls = new List(); + 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 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 moduleControls) + { + List searchControls = new List(); + List ownedSearchControls = new List(); + if (ControlObj != null) + { + searchControls.Add(ControlObj); + ownedSearchControls.Add(ControlObj); + } + + try + { + IEnumerable 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 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()) diff --git a/插件库/Lskj.PubModuleDetail/FrmMain.cs b/插件库/Lskj.PubModuleDetail/FrmMain.cs index 2a1e38a..8039594 100644 --- a/插件库/Lskj.PubModuleDetail/FrmMain.cs +++ b/插件库/Lskj.PubModuleDetail/FrmMain.cs @@ -157,7 +157,6 @@ namespace Lskj.PubModuleDetail string guid = this.Tag + ""; if (string.IsNullOrWhiteSpace(guid)) { - this.mControl.ReleaseResourcesForDispose(); return; } DllModule m = Manager.ModuleForms[guid]; @@ -180,7 +179,6 @@ namespace Lskj.PubModuleDetail } } } - // FormClosing fires before the control tree is disposed. Release the // DevExpress grids and their native resources as soon as the close is // confirmed; waiting for FrmMain.Dispose leaves GDI handles alive @@ -232,91 +230,20 @@ namespace Lskj.PubModuleDetail this.FormClosing -= OnClose; this.Disposed -= OnFrmMainDisposed; + // StaticControl performs the module-wide cache cleanup after the + // shell has confirmed the close. Remove only this form's cache key + // here; clearing the whole shared dictionary from a Disposed event + // could affect another tab that still uses the same model cache. Dictionary dataCaches = Model != null ? Model.DataCaches : null; - HashSet completedTasks; - if (dataCaches == null || - !TryDetachCompletedCacheTasks(dataCaches, out completedTasks)) - { - return; - } - - DisposeCompletedCacheTasks(completedTasks); - } - - /// - /// 释放模块预加载缓存中已完成任务的等待句柄。 - /// Task.Result 在等待时可能创建底层等待对象,仅清空字典 - /// 不会立即释放这些句柄。 - /// - private static void DisposeCompletedCacheTasks(IEnumerable tasks) - { - foreach (Task task in tasks) - { - try - { - task.Dispose(); - } - catch (ObjectDisposedException) - { - } - } - } - - /// - /// 仅当并行初始化全部完成时,才在同一同步区间摘除缓存任务。 - /// AddTask 使用同一个字典实例加锁,避免检查后又插入新任务。 - /// - private static bool TryDetachCompletedCacheTasks( - Dictionary dataCaches, - out HashSet completedTasks) - { - completedTasks = new HashSet(); try { - lock (dataCaches) - { - foreach (Hashtable cacheValues in dataCaches.Values) - { - if (cacheValues == null) - { - continue; - } - - foreach (object value in cacheValues.Values) - { - Task task = value as Task; - if (task == null) - { - continue; - } - - try - { - if (!task.IsCompleted) - { - completedTasks.Clear(); - return false; - } - } - catch (ObjectDisposedException) - { - continue; - } - - completedTasks.Add(task); - } - } - - dataCaches.Clear(); - } - - return true; + if (dataCaches != null) + dataCaches.RemoveCache(this); } - catch (InvalidOperationException) + catch (Exception exception) { - completedTasks.Clear(); - return false; + Debug.WriteLine("移除窗体动态缓存引用失败:" + exception); } } } diff --git a/插件库/Lskj.Report/FrmMain.Designer.cs b/插件库/Lskj.Report/FrmMain.Designer.cs index b33862f..12676c9 100644 --- a/插件库/Lskj.Report/FrmMain.Designer.cs +++ b/插件库/Lskj.Report/FrmMain.Designer.cs @@ -15,7 +15,7 @@ { if (disposing) { - DisposeReportGridViews(); + ReleaseReportGridReferences(); if (components != null) { components.Dispose(); diff --git a/插件库/Lskj.Report/FrmMain.cs b/插件库/Lskj.Report/FrmMain.cs index 54b9f7b..ae9fe80 100644 --- a/插件库/Lskj.Report/FrmMain.cs +++ b/插件库/Lskj.Report/FrmMain.cs @@ -12,7 +12,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; -using System.Linq; using System.Windows.Forms; using Lskj.Control; using Lskj.Model; @@ -100,7 +99,7 @@ namespace Lskj.Report private void OnFrmMainDisposed(object sender, EventArgs e) { - DisposeReportGridViews(); + ReleaseReportGridReferences(); mReportGridLocalizerViews.Clear(); mPreexistingGridLocalizerViews.Clear(); this.FormClosing -= OnClose; @@ -123,7 +122,7 @@ namespace Lskj.Report } } - private void DisposeReportGridViews() + private void ReleaseReportGridReferences() { if (mReportGridResourcesReleased) { @@ -136,79 +135,10 @@ namespace Lskj.Report { this.mControl.ReleaseResourcesForDispose(); } - - HashSet disposedViews = - new HashSet(); - foreach (System.Windows.Forms.Control control in - EnumerateControls(this.mControl)) - { - DevExpress.XtraGrid.GridControl gridControl = - control as DevExpress.XtraGrid.GridControl; - if (gridControl != null) - { - try - { - if (gridControl.DataSource != null) - { - gridControl.DataSource = null; - } - } - catch (Exception ex) - { - LogHelper.Instance.WriteError(ex, ResourceKeys.BaseReport); - } - - DevExpress.XtraGrid.Views.Base.BaseView[] views = - gridControl.ViewCollection - .Cast() - .ToArray(); - foreach (DevExpress.XtraGrid.Views.Base.BaseView view in views) - { - if (view == null || !disposedViews.Add(view)) - { - continue; - } - - try - { - view.Dispose(); - } - catch (Exception ex) - { - LogHelper.Instance.WriteError(ex, ResourceKeys.BaseReport); - } - } - } - - Type controlType = control.GetType(); - if (controlType.FullName != null && - controlType.FullName.StartsWith( - "DevExpress.XtraTreeList.", - StringComparison.Ordinal)) - { - try - { - PropertyInfo dataSourceProperty = - controlType.GetProperty( - "DataSource", - BindingFlags.Instance | - BindingFlags.Public); - if (dataSourceProperty != null && - dataSourceProperty.CanRead && - dataSourceProperty.CanWrite && - dataSourceProperty.GetValue(control, null) != null) - { - dataSourceProperty.SetValue(control, null, null); - } - } - catch (Exception ex) - { - LogHelper.Instance.WriteError(ex, ResourceKeys.BaseReport); - } - } - } - - ReleaseTrackedGridLocalizerViews(disposedViews); + // 此处不清空数据源,也不主动 Dispose GridView。报表窗口作为控件树 + // 的真实所有者会按 WinForms 生命周期释放控件;这里只解除全局 + // Localizer 的事件引用,避免已关闭报表继续被全局对象持有。 + ReleaseTrackedGridLocalizerViews(); } private void CaptureReportGridLocalizerViews() @@ -224,28 +154,8 @@ namespace Lskj.Report } } - private int ReleaseTrackedGridLocalizerViews( - HashSet disposedViews) + private int ReleaseTrackedGridLocalizerViews() { - foreach (DevExpress.XtraGrid.Views.Base.BaseView view in - mReportGridLocalizerViews) - { - if (view == null || - (disposedViews != null && !disposedViews.Add(view))) - { - continue; - } - - try - { - view.Dispose(); - } - catch (Exception exception) - { - LogHelper.Instance.WriteError(exception, ResourceKeys.BaseReport); - } - } - return RemoveGridLocalizerHandlers(mReportGridLocalizerViews); } @@ -420,23 +330,6 @@ namespace Lskj.Report handler.Target is DevExpress.XtraGrid.Views.Base.BaseView; } - private static IEnumerable EnumerateControls( - System.Windows.Forms.Control root) - { - if (root == null) - { - yield break; - } - yield return root; - foreach (System.Windows.Forms.Control child in root.Controls) - { - foreach (System.Windows.Forms.Control nested in EnumerateControls(child)) - { - yield return nested; - } - } - } - /// /// 说明:获取报表明细 /// 创建人:龚宇超