847 lines
29 KiB
C#
847 lines
29 KiB
C#
using DevExpress.XtraGrid.Views.Grid;
|
|
using DevExpress.XtraGrid.Views.BandedGrid;
|
|
using DevExpress.XtraTab;
|
|
using Lskj.Control.ZKFinger;
|
|
using Lskj.Model;
|
|
using Lskj.Util;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Windows.Forms;
|
|
using WinFormsControl = System.Windows.Forms.Control;
|
|
|
|
namespace Lskj.Control.Model
|
|
{
|
|
/// <summary>
|
|
/// WinForms-owned runtime state. A module registers the objects it creates
|
|
/// while it is being opened; closing a module disposes only that module's
|
|
/// scope. This deliberately has no control-tree traversal.
|
|
/// </summary>
|
|
public static class StaticControl
|
|
{
|
|
private static readonly object ModuleRegistrySync = new object();
|
|
|
|
/// <summary>
|
|
/// Owns cleanup callbacks for one opened module instance.
|
|
/// </summary>
|
|
public sealed class ModuleResourceScope : IDisposable
|
|
{
|
|
private sealed class Registration
|
|
{
|
|
internal readonly object Owner;
|
|
internal readonly Action Cleanup;
|
|
|
|
internal Registration(object owner, Action cleanup)
|
|
{
|
|
Owner = owner;
|
|
Cleanup = cleanup;
|
|
}
|
|
}
|
|
|
|
private readonly object _sync = new object();
|
|
private readonly List<Registration> _registrations =
|
|
new List<Registration>();
|
|
private bool _disposed;
|
|
|
|
public ModuleResourceScope(string moduleId)
|
|
{
|
|
ModuleId = moduleId ?? string.Empty;
|
|
TrackModuleScope(this);
|
|
}
|
|
|
|
public string ModuleId { get; private set; }
|
|
|
|
public bool IsDisposed
|
|
{
|
|
get
|
|
{
|
|
lock (_sync)
|
|
{
|
|
return _disposed;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Register(object owner, Action cleanup)
|
|
{
|
|
if (cleanup == null)
|
|
return;
|
|
|
|
bool runImmediately = false;
|
|
lock (_sync)
|
|
{
|
|
if (_disposed)
|
|
runImmediately = true;
|
|
else
|
|
_registrations.Add(new Registration(owner, cleanup));
|
|
}
|
|
|
|
if (runImmediately)
|
|
InvokeCleanup(cleanup);
|
|
}
|
|
|
|
public void Unregister(object owner)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
for (int index = _registrations.Count - 1; index >= 0; index--)
|
|
if (ReferenceEquals(_registrations[index].Owner, owner))
|
|
_registrations.RemoveAt(index);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
List<Registration> registrations;
|
|
lock (_sync)
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
|
|
_disposed = true;
|
|
registrations = new List<Registration>(_registrations);
|
|
_registrations.Clear();
|
|
}
|
|
|
|
// Reverse order mirrors normal ownership: the last registered
|
|
// helper is released before its owner.
|
|
for (int index = registrations.Count - 1; index >= 0; index--)
|
|
InvokeCleanup(registrations[index].Cleanup);
|
|
|
|
UntrackModuleScope(this);
|
|
}
|
|
|
|
private static void InvokeCleanup(Action cleanup)
|
|
{
|
|
try
|
|
{
|
|
cleanup();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(
|
|
"释放模块登记资源失败:" + exception);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void TrackModuleScope(ModuleResourceScope scope)
|
|
{
|
|
if (scope == null)
|
|
return;
|
|
|
|
lock (ActiveModuleScopesSync)
|
|
{
|
|
if (!ActiveModuleScopes.Contains(scope))
|
|
ActiveModuleScopes.Add(scope);
|
|
}
|
|
}
|
|
|
|
private static void UntrackModuleScope(ModuleResourceScope scope)
|
|
{
|
|
if (scope == null)
|
|
return;
|
|
|
|
lock (ActiveModuleScopesSync)
|
|
{
|
|
ActiveModuleScopes.Remove(scope);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases scopes created by legacy page-open paths that are not
|
|
/// present in Manager.ModuleScopes. Dispose is idempotent, so this is
|
|
/// safe to call after the managed module close pass.
|
|
/// </summary>
|
|
public static void CompleteAllModuleResourceScopes()
|
|
{
|
|
ModuleResourceScope[] scopes;
|
|
lock (ActiveModuleScopesSync)
|
|
{
|
|
scopes = ActiveModuleScopes.ToArray();
|
|
}
|
|
|
|
foreach (ModuleResourceScope scope in scopes)
|
|
{
|
|
if (scope != null)
|
|
scope.Dispose();
|
|
}
|
|
}
|
|
|
|
private sealed class ScopeCookie : IDisposable
|
|
{
|
|
private readonly ModuleResourceScope _previous;
|
|
private bool _disposed;
|
|
|
|
internal ScopeCookie(ModuleResourceScope previous)
|
|
{
|
|
_previous = previous;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
|
|
_disposed = true;
|
|
_currentModuleScope = _previous;
|
|
}
|
|
}
|
|
|
|
[ThreadStatic]
|
|
private static ModuleResourceScope _currentModuleScope;
|
|
|
|
// The table does not keep a disposed control alive. A short parent
|
|
// chain lookup is used only for controls created after PushModuleScope;
|
|
// there is never a global scan of the module's control tree.
|
|
private static readonly ConditionalWeakTable<WinFormsControl, ModuleResourceScope>
|
|
ModuleScopeOwners =
|
|
new ConditionalWeakTable<WinFormsControl, ModuleResourceScope>();
|
|
private static readonly object ActiveModuleScopesSync = new object();
|
|
private static readonly List<ModuleResourceScope> ActiveModuleScopes =
|
|
new List<ModuleResourceScope>();
|
|
private static readonly Dictionary<string, MyControl> ModuleSearchControls =
|
|
new Dictionary<string, MyControl>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
public static ModuleResourceScope CurrentModuleScope
|
|
{
|
|
get { return _currentModuleScope; }
|
|
}
|
|
|
|
public static IDisposable PushModuleScope(ModuleResourceScope scope)
|
|
{
|
|
ModuleResourceScope previous = _currentModuleScope;
|
|
_currentModuleScope = scope != null && !scope.IsDisposed ? scope : null;
|
|
return new ScopeCookie(previous);
|
|
}
|
|
|
|
private static ModuleResourceScope GetLiveCurrentModuleScope()
|
|
{
|
|
return _currentModuleScope != null && !_currentModuleScope.IsDisposed
|
|
? _currentModuleScope
|
|
: null;
|
|
}
|
|
|
|
public static void AttachModuleScope(
|
|
WinFormsControl owner,
|
|
ModuleResourceScope scope)
|
|
{
|
|
if (owner == null || scope == null || scope.IsDisposed)
|
|
return;
|
|
|
|
ModuleScopeOwners.Remove(owner);
|
|
ModuleScopeOwners.Add(owner, scope);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds a scope attached to the owner or one of its parents without
|
|
/// falling back to the calling thread's current scope.
|
|
/// </summary>
|
|
public static ModuleResourceScope FindAttachedModuleScope(
|
|
WinFormsControl owner)
|
|
{
|
|
ModuleResourceScope scope = FindParentModuleScope(owner);
|
|
if (scope != null)
|
|
return scope;
|
|
|
|
if (owner != null && ModuleScopeOwners.TryGetValue(owner, out scope) &&
|
|
scope != null && !scope.IsDisposed)
|
|
return scope;
|
|
return null;
|
|
}
|
|
|
|
public static ModuleResourceScope FindModuleScope(WinFormsControl owner)
|
|
{
|
|
ModuleResourceScope parentScope = FindParentModuleScope(owner);
|
|
if (parentScope != null)
|
|
return parentScope;
|
|
|
|
ModuleResourceScope scope;
|
|
if (owner != null && ModuleScopeOwners.TryGetValue(owner, out scope) &&
|
|
scope != null && !scope.IsDisposed)
|
|
return scope;
|
|
return _currentModuleScope != null && !_currentModuleScope.IsDisposed
|
|
? _currentModuleScope
|
|
: null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers a page created by a legacy caller that cannot go through
|
|
/// Manager.AddModuleToTab. The page GUID is made the module GUID as
|
|
/// well, and the page/form roots are attached to one scope so the
|
|
/// normal close path can discover and dispose that scope.
|
|
/// </summary>
|
|
public static ModuleResourceScope RegisterModulePage(
|
|
DllModule module,
|
|
XtraTabPage page,
|
|
Form form)
|
|
{
|
|
if (page == null)
|
|
return null;
|
|
|
|
string moduleId = Convert.ToString(page.Tag);
|
|
if (string.IsNullOrWhiteSpace(moduleId))
|
|
{
|
|
moduleId = Guid.NewGuid().ToString();
|
|
page.Tag = moduleId;
|
|
}
|
|
|
|
if (module != null)
|
|
{
|
|
module.Tag = moduleId;
|
|
if (form != null)
|
|
module.ModuleForm = form;
|
|
}
|
|
|
|
ModuleResourceScope scope = FindAttachedModuleScope(form) ??
|
|
FindAttachedModuleScope(page);
|
|
if (scope == null)
|
|
scope = new ModuleResourceScope(moduleId);
|
|
|
|
AttachModuleScope(page, scope);
|
|
AttachModuleScope(form, scope);
|
|
scope.Register(page, () =>
|
|
{
|
|
if (!page.IsDisposed)
|
|
page.Dispose();
|
|
});
|
|
if (form != null)
|
|
{
|
|
scope.Register(form, () =>
|
|
{
|
|
if (!form.IsDisposed)
|
|
form.Dispose();
|
|
});
|
|
}
|
|
return scope;
|
|
}
|
|
|
|
public static void RegisterModuleResource(
|
|
object owner,
|
|
Action cleanup)
|
|
{
|
|
RegisterModuleResource(owner, owner as WinFormsControl, cleanup);
|
|
}
|
|
|
|
public static void RegisterModuleResource(
|
|
object owner,
|
|
WinFormsControl context,
|
|
Action cleanup)
|
|
{
|
|
ModuleResourceScope scope = null;
|
|
if (context != null)
|
|
scope = FindModuleScope(context);
|
|
if (scope == null)
|
|
scope = GetLiveCurrentModuleScope();
|
|
if (scope != null)
|
|
scope.Register(owner, cleanup);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers one visual control as owned by its current module. A
|
|
/// ParentChanged subscription updates ownership when the same control
|
|
/// is explicitly moved to another live module; it never walks children.
|
|
/// </summary>
|
|
public static void RegisterOwnedControl(WinFormsControl owner)
|
|
{
|
|
if (owner == null)
|
|
return;
|
|
|
|
// A legacy control can be constructed before it is parented. Keep
|
|
// one exact ParentChanged hook so ownership is registered as soon
|
|
// as it joins a module, including controls prepared off the UI path.
|
|
owner.ParentChanged -= OnOwnedControlParentChanged;
|
|
owner.ParentChanged += OnOwnedControlParentChanged;
|
|
|
|
ModuleResourceScope scope = GetLiveCurrentModuleScope();
|
|
if (scope == null)
|
|
scope = FindParentModuleScope(owner);
|
|
if (scope == null)
|
|
return;
|
|
|
|
ModuleResourceScope existing;
|
|
if (ModuleScopeOwners.TryGetValue(owner, out existing) &&
|
|
ReferenceEquals(existing, scope))
|
|
{
|
|
return;
|
|
}
|
|
|
|
AttachModuleScope(owner, scope);
|
|
scope.Register(owner, () =>
|
|
{
|
|
// A complete subtree may have been moved to another module
|
|
// without changing every descendant's Parent. Follow the live
|
|
// parent scope and leave that subtree owned by the open module.
|
|
ModuleResourceScope parentScope = FindParentModuleScope(owner);
|
|
if (parentScope != null && !ReferenceEquals(parentScope, scope))
|
|
{
|
|
ModuleResourceScope previous = _currentModuleScope;
|
|
_currentModuleScope = parentScope;
|
|
try
|
|
{
|
|
RegisterOwnedControl(owner);
|
|
}
|
|
finally
|
|
{
|
|
_currentModuleScope = previous;
|
|
}
|
|
return;
|
|
}
|
|
|
|
ModuleResourceScope current;
|
|
if (!ModuleScopeOwners.TryGetValue(owner, out current) ||
|
|
!ReferenceEquals(current, scope))
|
|
{
|
|
return;
|
|
}
|
|
|
|
owner.ParentChanged -= OnOwnedControlParentChanged;
|
|
ModuleScopeOwners.Remove(owner);
|
|
if (!owner.IsDisposed)
|
|
owner.Dispose();
|
|
});
|
|
}
|
|
|
|
private static ModuleResourceScope FindParentModuleScope(WinFormsControl owner)
|
|
{
|
|
for (WinFormsControl current = owner == null ? null : owner.Parent;
|
|
current != null;
|
|
current = current.Parent)
|
|
{
|
|
ModuleResourceScope scope;
|
|
if (ModuleScopeOwners.TryGetValue(current, out scope) &&
|
|
scope != null && !scope.IsDisposed)
|
|
return scope;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static void OnOwnedControlParentChanged(object sender, EventArgs args)
|
|
{
|
|
WinFormsControl owner = sender as WinFormsControl;
|
|
if (owner == null || owner.IsDisposed)
|
|
return;
|
|
|
|
ModuleResourceScope parentScope = FindParentModuleScope(owner);
|
|
ModuleResourceScope currentScope;
|
|
if (parentScope != null &&
|
|
(!ModuleScopeOwners.TryGetValue(owner, out currentScope) ||
|
|
!ReferenceEquals(parentScope, currentScope)))
|
|
{
|
|
ModuleResourceScope previous = _currentModuleScope;
|
|
_currentModuleScope = parentScope;
|
|
try
|
|
{
|
|
RegisterOwnedControl(owner);
|
|
}
|
|
finally
|
|
{
|
|
_currentModuleScope = previous;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void RegisterModuleSearchControl(
|
|
WinFormsControl context,
|
|
MyControl searchControl)
|
|
{
|
|
if (searchControl == null)
|
|
return;
|
|
|
|
ModuleResourceScope scope = context == null
|
|
? GetLiveCurrentModuleScope()
|
|
: FindModuleScope(context);
|
|
if (scope == null || string.IsNullOrWhiteSpace(scope.ModuleId))
|
|
return;
|
|
|
|
string moduleId = scope.ModuleId;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
MyControl existing;
|
|
if (ModuleSearchControls.TryGetValue(moduleId, out existing))
|
|
{
|
|
if (ReferenceEquals(existing, searchControl))
|
|
return;
|
|
if (existing != null && !existing.IsDisposed)
|
|
return;
|
|
ModuleSearchControls.Remove(moduleId);
|
|
}
|
|
ModuleSearchControls[moduleId] = searchControl;
|
|
}
|
|
EventHandler disposed = null;
|
|
disposed = (sender, args) =>
|
|
{
|
|
searchControl.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
MyControl current;
|
|
if (ModuleSearchControls.TryGetValue(moduleId, out current) &&
|
|
ReferenceEquals(current, searchControl))
|
|
{
|
|
ModuleSearchControls.Remove(moduleId);
|
|
}
|
|
}
|
|
};
|
|
searchControl.Disposed += disposed;
|
|
scope.Register(searchControl, () =>
|
|
{
|
|
searchControl.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
MyControl current;
|
|
if (ModuleSearchControls.TryGetValue(moduleId, out current) &&
|
|
ReferenceEquals(current, searchControl))
|
|
{
|
|
ModuleSearchControls.Remove(moduleId);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public static MyControl FindModuleSearchControl(string moduleId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(moduleId))
|
|
return null;
|
|
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
MyControl searchControl;
|
|
if (!ModuleSearchControls.TryGetValue(moduleId, out searchControl))
|
|
return null;
|
|
if (searchControl == null || searchControl.IsDisposed)
|
|
{
|
|
ModuleSearchControls.Remove(moduleId);
|
|
return null;
|
|
}
|
|
return searchControl;
|
|
}
|
|
}
|
|
|
|
public static void RegisterConditionPanel(
|
|
string key,
|
|
ModuleConditionsPanelEx panel)
|
|
{
|
|
if (panel == null)
|
|
return;
|
|
|
|
key = key ?? string.Empty;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
ModuleConditionsPanelEx previous;
|
|
if (ConditionsPanelDic.TryGetValue(key, out previous) &&
|
|
previous != null && previous.IsDisposed)
|
|
{
|
|
ConditionsPanelDic.Remove(key);
|
|
}
|
|
|
|
// A key can be reused by a second module instance. Never
|
|
// dispose the first live dialog from the second registration.
|
|
ConditionsPanelDic[key] = panel;
|
|
}
|
|
EventHandler disposed = null;
|
|
disposed = (sender, args) =>
|
|
{
|
|
panel.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
ModuleConditionsPanelEx current;
|
|
if (ConditionsPanelDic.TryGetValue(key, out current) &&
|
|
ReferenceEquals(current, panel))
|
|
{
|
|
ConditionsPanelDic.Remove(key);
|
|
}
|
|
}
|
|
};
|
|
panel.Disposed += disposed;
|
|
RegisterModuleResource(panel, panel, () =>
|
|
{
|
|
panel.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
ModuleConditionsPanelEx current;
|
|
if (ConditionsPanelDic.TryGetValue(key, out current) &&
|
|
ReferenceEquals(current, panel))
|
|
{
|
|
ConditionsPanelDic.Remove(key);
|
|
}
|
|
}
|
|
if (!panel.IsDisposed)
|
|
{
|
|
panel.Dispose();
|
|
}
|
|
});
|
|
}
|
|
|
|
public static void RegisterProtectedPage(XtraTabPage page)
|
|
{
|
|
if (page == null)
|
|
return;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
if (!DogVerifyModuleForms.Contains(page))
|
|
DogVerifyModuleForms.Add(page);
|
|
}
|
|
|
|
EventHandler disposed = null;
|
|
disposed = (sender, args) =>
|
|
{
|
|
page.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
DogVerifyModuleForms.Remove(page);
|
|
}
|
|
};
|
|
page.Disposed += disposed;
|
|
RegisterModuleResource(page, () =>
|
|
{
|
|
page.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
DogVerifyModuleForms.Remove(page);
|
|
}
|
|
});
|
|
}
|
|
|
|
public static void RegisterProtectedForm(IForm form)
|
|
{
|
|
if (form == null || form.SubForm == null)
|
|
return;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
if (!DogVerifyNoPageForms.Contains(form))
|
|
DogVerifyNoPageForms.Add(form);
|
|
}
|
|
|
|
Form subForm = form.SubForm;
|
|
EventHandler disposed = null;
|
|
disposed = (sender, args) =>
|
|
{
|
|
subForm.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
DogVerifyNoPageForms.Remove(form);
|
|
}
|
|
};
|
|
subForm.Disposed += disposed;
|
|
RegisterModuleResource(subForm, () =>
|
|
{
|
|
subForm.Disposed -= disposed;
|
|
lock (ModuleRegistrySync)
|
|
{
|
|
DogVerifyNoPageForms.Remove(form);
|
|
}
|
|
});
|
|
}
|
|
|
|
internal static void ReleaseGridViewReferences(GridView gridView)
|
|
{
|
|
if (gridView == null)
|
|
return;
|
|
|
|
GridDragGrid.DisposeRegistrations(
|
|
GridViewDragGridDic,
|
|
TargetViewDragGridDic,
|
|
gridView);
|
|
BandedGridDragGrid.DisposeRegistrations(
|
|
StaticBandedControl.BandedGridViewDragGridDic,
|
|
StaticBandedControl.BandedTargetViewDragGridDic,
|
|
gridView as BandedGridView,
|
|
gridView);
|
|
GridDragGrid.ClearSourceReferenceIfUnused(gridView);
|
|
if (ReferenceEquals(_RightMenuGridView, gridView))
|
|
RightMenuGridView = null;
|
|
}
|
|
|
|
private static void OnRightMenuGridViewDisposed(object sender, EventArgs args)
|
|
{
|
|
GridView view = sender as GridView;
|
|
if (ReferenceEquals(_RightMenuGridView, view))
|
|
RightMenuGridView = null;
|
|
}
|
|
|
|
private static void OnBomUnionPageDisposed(object sender, EventArgs args)
|
|
{
|
|
XtraTabPage page = sender as XtraTabPage;
|
|
if (ReferenceEquals(BomUnionPage, page))
|
|
SetBomUnionPage(null);
|
|
}
|
|
|
|
private static void OnRightMenuMyControlDisposed(object sender, EventArgs args)
|
|
{
|
|
MyControl control = sender as MyControl;
|
|
if (ReferenceEquals(RightMenuMyControl, control))
|
|
SetRightMenuMyControl(null);
|
|
}
|
|
|
|
private static void OnAddParentGridDisposed(object sender, EventArgs args)
|
|
{
|
|
GridControlEx grid = sender as GridControlEx;
|
|
if (ReferenceEquals(AddParentGrid.Value, grid))
|
|
SetAddParentGrid(new KeyValuePair<string, GridControlEx>());
|
|
}
|
|
|
|
/// <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;
|
|
|
|
public static KeyValuePair<string, GridControlEx> AddParentGrid =
|
|
new KeyValuePair<string, GridControlEx>();
|
|
public static void SetAddParentGrid(
|
|
KeyValuePair<string, GridControlEx> value)
|
|
{
|
|
if (ReferenceEquals(AddParentGrid.Value, value.Value) &&
|
|
string.Equals(AddParentGrid.Key, value.Key, StringComparison.Ordinal))
|
|
{
|
|
return;
|
|
}
|
|
|
|
GridControlEx previous = AddParentGrid.Value;
|
|
if (previous != null)
|
|
previous.Disposed -= OnAddParentGridDisposed;
|
|
|
|
AddParentGrid = value;
|
|
GridControlEx current = value.Value;
|
|
if (current == null)
|
|
return;
|
|
|
|
current.Disposed += OnAddParentGridDisposed;
|
|
RegisterModuleResource(current, () =>
|
|
{
|
|
current.Disposed -= OnAddParentGridDisposed;
|
|
if (ReferenceEquals(AddParentGrid.Value, current))
|
|
AddParentGrid = new KeyValuePair<string, GridControlEx>();
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当前右键点击时的表格
|
|
/// </summary>
|
|
public static GridView _RightMenuGridView;
|
|
public static GridView RightMenuGridView
|
|
{
|
|
get { return _RightMenuGridView; }
|
|
set
|
|
{
|
|
if (ReferenceEquals(_RightMenuGridView, value))
|
|
{
|
|
Comprefix = string.Empty;
|
|
ReturnRowLisy.Clear();
|
|
return;
|
|
}
|
|
|
|
if (_RightMenuGridView != null)
|
|
_RightMenuGridView.Disposed -= OnRightMenuGridViewDisposed;
|
|
|
|
_RightMenuGridView = value;
|
|
Comprefix = string.Empty;
|
|
ReturnRowLisy.Clear();
|
|
if (value == null)
|
|
return;
|
|
|
|
value.Disposed += OnRightMenuGridViewDisposed;
|
|
RegisterModuleResource(
|
|
value,
|
|
value.GridControl as WinFormsControl,
|
|
() =>
|
|
{
|
|
value.Disposed -= OnRightMenuGridViewDisposed;
|
|
if (ReferenceEquals(_RightMenuGridView, value))
|
|
_RightMenuGridView = null;
|
|
});
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// bom附件修改时的关联页签
|
|
/// </summary>
|
|
public static XtraTabPage BomUnionPage;
|
|
public static void SetBomUnionPage(XtraTabPage value)
|
|
{
|
|
if (ReferenceEquals(BomUnionPage, value))
|
|
return;
|
|
|
|
if (BomUnionPage != null)
|
|
BomUnionPage.Disposed -= OnBomUnionPageDisposed;
|
|
|
|
BomUnionPage = value;
|
|
if (value == null)
|
|
return;
|
|
|
|
value.Disposed += OnBomUnionPageDisposed;
|
|
RegisterModuleResource(value, () =>
|
|
{
|
|
value.Disposed -= OnBomUnionPageDisposed;
|
|
if (ReferenceEquals(BomUnionPage, value))
|
|
BomUnionPage = null;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当前右键点击时的控件对象
|
|
/// </summary>
|
|
public static MyControl RightMenuMyControl;
|
|
public static void SetRightMenuMyControl(MyControl value)
|
|
{
|
|
if (ReferenceEquals(RightMenuMyControl, value))
|
|
return;
|
|
|
|
if (RightMenuMyControl != null)
|
|
RightMenuMyControl.Disposed -= OnRightMenuMyControlDisposed;
|
|
|
|
RightMenuMyControl = value;
|
|
if (value == null)
|
|
return;
|
|
|
|
value.Disposed += OnRightMenuMyControlDisposed;
|
|
RegisterModuleResource(
|
|
value,
|
|
value.MainGridEx,
|
|
() =>
|
|
{
|
|
value.Disposed -= OnRightMenuMyControlDisposed;
|
|
if (ReferenceEquals(RightMenuMyControl, value))
|
|
RightMenuMyControl = null;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当前右键点击时的表格的列前缀
|
|
/// </summary>
|
|
public static string Comprefix;
|
|
/// <summary>
|
|
/// 浏览器返回数据
|
|
/// </summary>
|
|
public static List<DataRow> ReturnRowLisy = new List<DataRow>();
|
|
}
|
|
}
|