173 lines
5.8 KiB
C#
173 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace DevComponents.DotNetBar
|
|
{
|
|
/// <summary>
|
|
/// Class that tracks lists of all controls that host currently open popups.
|
|
/// </summary>
|
|
public static class PopupManager
|
|
{
|
|
#region Constructor
|
|
private static List<WeakReference> _RegisteredPopups = new List<WeakReference>();
|
|
private static ReaderWriterLock ReadWritePopupsListLock;
|
|
|
|
static PopupManager()
|
|
{
|
|
PopupManager.ReadWritePopupsListLock = new ReaderWriterLock();
|
|
}
|
|
#endregion
|
|
|
|
#region Implementation
|
|
/// <summary>
|
|
/// Registers IOwnerMenuSupport popup host in response to host displaying its first popup.
|
|
/// </summary>
|
|
/// <param name="popupHost">IOwnerMenuSupport host to register</param>
|
|
public static void RegisterPopup(IOwnerMenuSupport popupHost)
|
|
{
|
|
if (popupHost == null) return;
|
|
if (GetHostReference(popupHost) == null)
|
|
{
|
|
WeakReference reference = new WeakReference(popupHost);
|
|
reference.Target = popupHost;
|
|
|
|
LockCookie cookie1 = new LockCookie();
|
|
bool readerLockHeld = PopupManager.ReadWritePopupsListLock.IsReaderLockHeld;
|
|
if (readerLockHeld)
|
|
{
|
|
cookie1 = PopupManager.ReadWritePopupsListLock.UpgradeToWriterLock(-1);
|
|
}
|
|
else
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.AcquireWriterLock(-1);
|
|
}
|
|
try
|
|
{
|
|
_RegisteredPopups.Add(reference);
|
|
}
|
|
finally
|
|
{
|
|
if (readerLockHeld)
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.DowngradeFromWriterLock(ref cookie1);
|
|
}
|
|
else
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.ReleaseWriterLock();
|
|
}
|
|
}
|
|
|
|
popupHost = null;
|
|
}
|
|
}
|
|
|
|
private static WeakReference GetHostReference(IOwnerMenuSupport host)
|
|
{
|
|
List<WeakReference> registeredControls = _RegisteredPopups;
|
|
if (registeredControls == null) return null;
|
|
|
|
PopupManager.ReadWritePopupsListLock.AcquireReaderLock(-1);
|
|
try
|
|
{
|
|
foreach (WeakReference item in registeredControls)
|
|
{
|
|
object target = item.Target;
|
|
if (target != null && target.Equals(host))
|
|
return item;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.ReleaseReaderLock();
|
|
}
|
|
return null;
|
|
}
|
|
/// <summary>
|
|
/// Unregisters IOwnerMenuSupport popup host in response to host closing its last popup.
|
|
/// </summary>
|
|
/// <param name="popupHost">IOwnerMenuSupport host to unregister</param>
|
|
public static void UnregisterPopup(IOwnerMenuSupport popupHost)
|
|
{
|
|
if (popupHost == null) return;
|
|
LockCookie cookie1 = new LockCookie();
|
|
bool readerLockHeld = PopupManager.ReadWritePopupsListLock.IsReaderLockHeld;
|
|
if (readerLockHeld)
|
|
{
|
|
cookie1 = PopupManager.ReadWritePopupsListLock.UpgradeToWriterLock(-1);
|
|
}
|
|
else
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.AcquireWriterLock(-1);
|
|
}
|
|
try
|
|
{
|
|
|
|
foreach (WeakReference item in _RegisteredPopups)
|
|
{
|
|
object target = item.Target;
|
|
if (target != null && target.Equals(popupHost))
|
|
{
|
|
_RegisteredPopups.Remove(item);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (readerLockHeld)
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.DowngradeFromWriterLock(ref cookie1);
|
|
}
|
|
else
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.ReleaseWriterLock();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Closes all currently open popups.
|
|
/// </summary>
|
|
public static void CloseAllPopups()
|
|
{
|
|
CloseAllPopups(null);
|
|
}
|
|
/// <summary>
|
|
/// Closes all currently open popups excluding specified popup host.
|
|
/// </summary>
|
|
/// <param name="excludeHost">IOwnerMenuSupport host to exclude from closing or null</param>
|
|
public static void CloseAllPopups(IOwnerMenuSupport excludeHost)
|
|
{
|
|
WeakReference[] references;
|
|
PopupManager.ReadWritePopupsListLock.AcquireReaderLock(-1);
|
|
try
|
|
{
|
|
references = new WeakReference[_RegisteredPopups.Count];
|
|
_RegisteredPopups.CopyTo(references);
|
|
}
|
|
finally
|
|
{
|
|
PopupManager.ReadWritePopupsListLock.ReleaseReaderLock();
|
|
}
|
|
|
|
foreach (WeakReference reference in references)
|
|
{
|
|
object target = reference.Target;
|
|
if (reference.IsAlive)
|
|
{
|
|
if (target != null)
|
|
{
|
|
IOwnerMenuSupport popupHost = target as IOwnerMenuSupport;
|
|
if (popupHost != null && popupHost != excludeHost)
|
|
{
|
|
popupHost.ClosePopups();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|