fix(legacy): finalize hosted module lifecycle cleanup
This commit is contained in:
@@ -46,23 +46,62 @@ namespace Lskj.Control.Model
|
||||
Dictionary<GridView, List<GridDragGrid>> registrations,
|
||||
GridView gridView)
|
||||
{
|
||||
if (registrations == null)
|
||||
return;
|
||||
|
||||
// A module-close operation must only remove registrations that
|
||||
// reference the exact view being closed. Never infer ownership
|
||||
// from GridControl.IsDisposed here: another open tab can be in a
|
||||
// transient initialization/dispose state and its registration
|
||||
// must remain untouched.
|
||||
foreach (KeyValuePair<GridView, List<GridDragGrid>> entry in registrations.ToList())
|
||||
{
|
||||
bool removeKey = ReferenceEquals(entry.Key, gridView);
|
||||
foreach (GridDragGrid registration in entry.Value.ToList())
|
||||
List<GridDragGrid> registrationsForView = entry.Value;
|
||||
if (registrationsForView == null)
|
||||
{
|
||||
if (removeKey || registration == null || registration._disposed || registration.References(gridView))
|
||||
registrations.Remove(entry.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (GridDragGrid registration in registrationsForView.ToList())
|
||||
{
|
||||
if (removeKey || registration == null || registration._disposed ||
|
||||
registration.References(gridView))
|
||||
{
|
||||
if (registration != null)
|
||||
registration.Dispose();
|
||||
entry.Value.Remove(registration);
|
||||
{
|
||||
try
|
||||
{
|
||||
registration.Dispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("清理表格拖拽注册失败:" + exception);
|
||||
}
|
||||
}
|
||||
registrationsForView.Remove(registration);
|
||||
}
|
||||
}
|
||||
if (removeKey || entry.Value.Count == 0)
|
||||
if (removeKey || registrationsForView.Count == 0)
|
||||
registrations.Remove(entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsDisposedView(GridView view)
|
||||
{
|
||||
if (view == null)
|
||||
return true;
|
||||
try
|
||||
{
|
||||
return view.GridControl == null || view.GridControl.IsDisposed;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool References(GridView gridView)
|
||||
{
|
||||
return gridView != null &&
|
||||
@@ -115,8 +154,16 @@ namespace Lskj.Control.Model
|
||||
/// <param name="tarGridView">目标GridView.</param>
|
||||
public GridDragGrid(GridView sourceView, GridView targetView)
|
||||
{
|
||||
// Do not put an incomplete registration in the global dictionaries.
|
||||
// A GridView without an owner GridControl cannot receive the drag
|
||||
// events below and would otherwise remain a strong static reference.
|
||||
if (IsDisposedView(sourceView) || IsDisposedView(targetView))
|
||||
return;
|
||||
|
||||
this._sourceGridView = sourceView;
|
||||
this._targetGridView = targetView;
|
||||
try
|
||||
{
|
||||
//记录所有拖拽类到来源表中,后每次进入目标表禁用其他拖拽类的拖拽事件
|
||||
if (StaticControl.GridViewDragGridDic.ContainsKey(sourceView))
|
||||
{
|
||||
@@ -162,6 +209,21 @@ namespace Lskj.Control.Model
|
||||
{
|
||||
this._targetGridView.Disposed += OnGridViewDisposed;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Registration is a two-dictionary operation. If event wiring
|
||||
// fails, undo everything that was attached before rethrowing.
|
||||
try
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("回滚表格拖拽注册失败:" + exception);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGridViewDisposed(object sender, EventArgs e)
|
||||
@@ -214,7 +276,8 @@ namespace Lskj.Control.Model
|
||||
targetGridView,
|
||||
this);
|
||||
|
||||
if (ReferenceEquals(StaticControl.SourceDragGridView, sourceGridView))
|
||||
if (ReferenceEquals(StaticControl.SourceDragGridView, sourceGridView) &&
|
||||
!HasRegistrationForView(sourceGridView))
|
||||
{
|
||||
StaticControl.SourceDragGridView = null;
|
||||
}
|
||||
@@ -226,6 +289,45 @@ namespace Lskj.Control.Model
|
||||
_targetGridView = null;
|
||||
}
|
||||
|
||||
private static bool HasRegistrationForView(GridView gridView)
|
||||
{
|
||||
if (gridView == null)
|
||||
return false;
|
||||
|
||||
return HasRegistration(StaticControl.GridViewDragGridDic, gridView) ||
|
||||
HasRegistration(StaticControl.TargetViewDragGridDic, gridView);
|
||||
}
|
||||
|
||||
internal static void ClearSourceReferenceIfUnused(GridView gridView)
|
||||
{
|
||||
if (gridView != null &&
|
||||
ReferenceEquals(StaticControl.SourceDragGridView, gridView) &&
|
||||
!HasRegistrationForView(gridView))
|
||||
{
|
||||
StaticControl.SourceDragGridView = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasRegistration<TKey>(
|
||||
Dictionary<TKey, List<GridDragGrid>> registrations,
|
||||
GridView gridView)
|
||||
where TKey : class
|
||||
{
|
||||
if (registrations == null || gridView == null)
|
||||
return false;
|
||||
|
||||
foreach (KeyValuePair<TKey, List<GridDragGrid>> entry in registrations)
|
||||
{
|
||||
List<GridDragGrid> items = entry.Value;
|
||||
if (items == null)
|
||||
continue;
|
||||
foreach (GridDragGrid item in items)
|
||||
if (item != null && !item._disposed && item.References(gridView))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void RemoveRegistration<TKey>(
|
||||
Dictionary<TKey, List<GridDragGrid>> registrations,
|
||||
TKey key,
|
||||
@@ -237,12 +339,23 @@ namespace Lskj.Control.Model
|
||||
return;
|
||||
}
|
||||
|
||||
if (registrations == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<GridDragGrid> registrationsForView;
|
||||
if (!registrations.TryGetValue(key, out registrationsForView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (registrationsForView == null)
|
||||
{
|
||||
registrations.Remove(key);
|
||||
return;
|
||||
}
|
||||
|
||||
registrationsForView.Remove(registration);
|
||||
if (registrationsForView.Count == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user