Files
lserp_cs_6.0/插件库/Lskj.Control/Model/StaticControl.cs
T

286 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraTab;
using Lskj.Control.ZKFinger;
using Lskj.Util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lskj.Model;
using System.Reflection;
using WinFormsControl = System.Windows.Forms.Control;
namespace Lskj.Control.Model
{
public static class StaticControl
{
/// <summary>
/// Releases static references owned by a closed legacy module. Cleanup is
/// best-effort so it cannot change the module close result.
/// </summary>
public static void ReleaseModuleReferences(WinFormsControl moduleRoot, XtraTabPage modulePage, string moduleCode)
{
List<GridView> gridViews = new List<GridView>();
try
{
gridViews = CollectGridViews(moduleRoot);
}
catch (Exception exception)
{
TraceCleanupFailure("收集表格引用", exception);
}
try
{
foreach (GridView gridView in gridViews)
{
try
{
RemoveGridReferences(gridView);
}
catch (Exception exception)
{
TraceCleanupFailure("释放表格拖拽引用", exception);
}
}
TryCleanup(() => RemoveConditionPanels(moduleCode), "释放条件面板引用");
TryCleanup(() => RemoveProtectedReferences(moduleRoot, modulePage), "释放权限保护引用");
TryCleanup(() => ClearRightMenuReferences(moduleRoot, gridViews), "释放右键菜单引用");
TryCleanup(
() => StaticBandedControl.ReleaseModuleReferences(moduleRoot, modulePage, moduleCode),
"释放带状表格引用");
}
finally
{
// DynamicModel caches retain completed tasks, result tables and
// their closures. Always release them after other references.
TryCleanup(() => ClearDataCaches(moduleRoot), "释放动态数据缓存");
}
}
private static void TryCleanup(Action cleanup, string operation)
{
try
{
cleanup();
}
catch (Exception exception)
{
TraceCleanupFailure(operation, exception);
}
}
private static void TraceCleanupFailure(string operation, Exception exception)
{
Debug.WriteLine("释放旧模块引用失败[" + operation + "]" + exception);
}
private static List<GridView> CollectGridViews(WinFormsControl root)
{
List<GridView> result = new List<GridView>();
if (root == null)
return result;
foreach (WinFormsControl control in EnumerateControls(root))
{
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);
}
return result;
}
private static IEnumerable<WinFormsControl> EnumerateControls(WinFormsControl root)
{
yield return root;
foreach (WinFormsControl child in root.Controls)
foreach (WinFormsControl nested in EnumerateControls(child))
yield return nested;
}
private static void RemoveGridReferences(GridView gridView)
{
GridDragGrid.DisposeRegistrations(GridViewDragGridDic, TargetViewDragGridDic, gridView);
if (ReferenceEquals(SourceDragGridView, gridView) ||
(SourceDragGridView != null && SourceDragGridView.GridControl != null && SourceDragGridView.GridControl.IsDisposed))
SourceDragGridView = null;
}
private static void RemoveConditionPanels(string moduleCode)
{
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)
ConditionsPanelDic.Remove(key);
}
}
private static void RemoveProtectedReferences(WinFormsControl root, XtraTabPage page)
{
while (page != null && DogVerifyModuleForms.Remove(page))
{
}
foreach (XtraTabPage item in DogVerifyModuleForms.ToList())
if (item == null || item.IsDisposed || IsContained(root, item))
DogVerifyModuleForms.Remove(item);
foreach (IForm item in DogVerifyNoPageForms.ToList())
if (item == null || item.SubForm == null || item.SubForm.IsDisposed || IsContained(root, item.SubForm))
DogVerifyNoPageForms.Remove(item);
}
private static bool IsContained(WinFormsControl root, WinFormsControl value)
{
if (root == null || value == null)
return false;
if (ReferenceEquals(root, value))
return true;
foreach (WinFormsControl child in root.Controls)
if (IsContained(child, value))
return true;
return false;
}
private static void ClearRightMenuReferences(WinFormsControl root, List<GridView> gridViews)
{
if (_RightMenuGridView != null && (gridViews.Contains(_RightMenuGridView) ||
(_RightMenuGridView.GridControl != null && _RightMenuGridView.GridControl.IsDisposed)))
RightMenuGridView = null;
if (RightMenuMyControl != null && RightMenuMyControl.MainGridEx != null &&
(RightMenuMyControl.MainGridEx.IsDisposed || IsContained(root, RightMenuMyControl.MainGridEx)))
RightMenuMyControl = null;
if (BomUnionPage != null && (BomUnionPage.IsDisposed || IsContained(root, BomUnionPage)))
BomUnionPage = null;
if (AddParentGrid.Value != null && (AddParentGrid.Value.IsDisposed || IsContained(root, AddParentGrid.Value)))
AddParentGrid = new KeyValuePair<string, GridControlEx>();
}
private static void ClearDataCaches(WinFormsControl root)
{
if (root == null)
return;
// Clear the root first because child enumeration can fail while a
// DevExpress control is disposing its child collection.
ClearDynamicModels(root);
try
{
foreach (WinFormsControl control in EnumerateControls(root).Skip(1).ToList())
ClearDynamicModels(control);
}
catch (Exception exception)
{
TraceCleanupFailure("遍历动态数据缓存", exception);
}
}
private static void ClearDynamicModels(object instance)
{
if (instance == null)
return;
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
for (Type type = instance.GetType(); type != null; type = type.BaseType)
foreach (FieldInfo field in type.GetFields(flags | BindingFlags.DeclaredOnly))
try
{
ClearDynamicModel(field.GetValue(instance));
}
catch (Exception exception)
{
Debug.WriteLine("清理动态缓存字段失败:" + exception);
}
}
private static void ClearDynamicModel(object value)
{
DynamicModel model = value as DynamicModel;
if (model == null || model.DataCaches == null)
return;
Dictionary<object, Hashtable> caches = model.DataCaches;
foreach (Hashtable cache in caches.Values.OfType<Hashtable>().ToList())
{
foreach (IDisposable item in cache.Values.OfType<IDisposable>().ToList())
try { item.Dispose(); } catch { }
cache.Clear();
}
caches.Clear();
model.DataCaches = null;
}
/// <summary>
/// 记录当前U盾权限窗口
/// </summary>
public static List<XtraTabPage> DogVerifyModuleForms = new List<XtraTabPage>();
public static List<IForm> DogVerifyNoPageForms = new List<IForm>();
/// <summary>
///模块打开时的条件界面
/// </summary>
public static Dictionary<string, ModuleConditionsPanelEx> ConditionsPanelDic = new Dictionary<string, ModuleConditionsPanelEx>();
/// <summary>
/// 表格拖拽类,key值为源表
/// </summary>
public static Dictionary<GridView, List<GridDragGrid>> GridViewDragGridDic = new Dictionary<GridView, List<GridDragGrid>>();
/// <summary>
/// 表格拖拽类,key值为目标表
/// </summary>
public static Dictionary<GridView, List<GridDragGrid>> TargetViewDragGridDic = new Dictionary<GridView, List<GridDragGrid>>();
/// <summary>
/// 当前拖拽源表格
/// </summary>
public static GridView SourceDragGridView;
/// <summary>
/// 指纹识别模块
/// </summary>
public static FingerHelper fingerHelper;
///// <summary>
///// 外部exe进程
///// </summary>
//public static Dictionary<ExeType, Process> loadExeProcess = new Dictionary<ExeType, Process>();
/// <summary>
/// 打开的Add模块对应的父表格控件(模块编号,GridControlEx)
/// </summary>
public static KeyValuePair<string, GridControlEx> AddParentGrid = new KeyValuePair<string, GridControlEx>();
/// <summary>
/// 当前右键点击时的表格
/// </summary>
public static GridView _RightMenuGridView;
public static GridView RightMenuGridView
{
get
{
return StaticControl._RightMenuGridView;
}
set
{
StaticControl._RightMenuGridView = value;
StaticControl.Comprefix = "";
StaticControl.ReturnRowLisy.Clear();
}
}
/// <summary>
/// bom附件修改时的关联页签
/// </summary>
public static XtraTabPage BomUnionPage;
/// <summary>
/// 当前右键点击时的控件对象
/// </summary>
public static MyControl RightMenuMyControl;
/// <summary>
/// 当前右键点击时的表格的列前缀
/// </summary>
public static string Comprefix;
/// <summary>
/// 浏览器返回数据
/// </summary>
public static List<DataRow> ReturnRowLisy = new List<DataRow>();
}
}