private void UnsubscribeNotifyChangedEvent(object value, EventChangeType eventChangeType, ICollection parentCollection)
{
if (value == null)
{
return;
}
lock (_lockObject)
{
ConditionalWeakTable<object, IWeakEventListener> eventsTable;
List<IWeakEventListener> eventsList;
switch (eventChangeType)
{
case EventChangeType.Property:
eventsTable = _weakPropertyChangedListenersTable;
eventsList = _weakPropertyChangedListeners;
if (parentCollection != null)
{
List<WeakReference> collectionItems;
if (_collectionItems.TryGetValue(parentCollection, out collectionItems))
{
// TODO: Consider less costly way to determine this
for (var i = 0; i < collectionItems.Count; i++)
{
if (ReferenceEquals(collectionItems[i].Target, value))
{
collectionItems.RemoveAt(i--);
break;
}
}
}
}
break;
case EventChangeType.Collection:
eventsTable = _weakCollectionChangedListenersTable;
eventsList = _weakCollectionChangedListeners;
break;
default:
throw new ArgumentOutOfRangeException("eventChangeType");
}
IWeakEventListener oldSubscription;
if (eventsTable != null && eventsTable.TryGetValue(value, out oldSubscription))
{
if (oldSubscription != null)
{
oldSubscription.Detach();
eventsList.Remove(oldSubscription);
}
eventsTable.Remove(value);
}
if (value is ICollection)
{
List<WeakReference> collectionItems;
if (_collectionItems.TryGetValue(value, out collectionItems))
{
foreach (var item in collectionItems)
{
if (item.IsAlive)
{
var actualItem = item.Target;
UnsubscribeNotifyChangedEvents(actualItem, parentCollection);
}
}
collectionItems.Clear();
_collectionItems.Remove(value);
}
}
}
}
#endregion