public void ResetListeners(int startIndex, DataSourceChangedEventHandler subscriber) { // Note: Resetting the TerminalNode is not supported, and never needed. for (int nPtr = startIndex; nPtr < Count - 1; nPtr++) { this[nPtr].Reset(subscriber); } }
public void Reset(DataSourceChangedEventHandler subscriber = null) { if (subscriber != null) { Unsubscribe(subscriber); } if (SourceKind != SourceKindEnum.Empty && SourceKind != SourceKindEnum.TerminalNode && Status.IsWatching()) { object data = Data; if (data != null) { RemoveSubscriptions(data); } } }
public bool Unsubscribe(DataSourceChangedEventHandler subscriber) { if (DataSourceChanged == null) { return(false); // It's not there. } else { Delegate[] subscriberList = DataSourceChanged.GetInvocationList(); if (subscriberList.FirstOrDefault((x) => x == (Delegate)subscriber) == null) { return(false); // Not there. } else { DataSourceChanged -= subscriber; return(true); // We removed it. } } }
public bool Subscribe(DataSourceChangedEventHandler subscriber) { if (DataSourceChanged == null) { DataSourceChanged = subscriber; return(true); // We added it. } else { Delegate[] subscriberList = DataSourceChanged.GetInvocationList(); if (subscriberList.FirstOrDefault((x) => x == (Delegate)subscriber) == null) { DataSourceChanged += subscriber; return(true); // We added it. } else { return(false); // Already there. } } }
/// <summary> /// /// </summary> /// <param name="pathListeners"></param> /// <param name="index"></param> /// <param name="newListenerProvider"></param> /// <param name="subscriber"></param> /// <param name="newListener"></param> /// <returns>True if the path listener is ready to start listening to property and/or collection change events.</returns> public ObservableSourceStatusEnum ReplaceListener(int index, ref ObservableSourceProvider newListenerProvider, DataSourceChangedEventHandler subscriber, out ObservableSource newListener) { if (index == Count - 1) { System.Diagnostics.Debug.Assert(index != Count - 1, "We are replacing the terminal listener. This is not good."); } ObservableSource oldListener = this[index]; if (newListenerProvider != null) { newListener = newListenerProvider.CreateObservableSource(); newListenerProvider = null; } else { newListener = null; } bool wasListening = oldListener?.IsListeningForNewDC == true; if (newListener?.IsListeningForNewDC != true) { // The new ObservableSource is not responding to any change events. if (index == 0) { System.Diagnostics.Debug.WriteLine("The Source Root is not listening."); } else if (wasListening) { System.Diagnostics.Debug.WriteLine($"The ObservableSource at node {index} is no longer listening to any change events."); } } if (oldListener != null) { #if DEBUG bool wasRemoved = oldListener.Unsubscribe(subscriber); System.Diagnostics.Debug.Assert(wasListening == wasRemoved, "Was Listening does not agree with WasRemoved."); // Remove PropertyChanged or CollectionChanged event handlers, if any. oldListener.Reset(); #else // Remove all event handlers. oldListener.Reset(subscriber); #endif } if (newListener == null) { // It is the caller's responsibility to cleanup the dependent nodes. return(ObservableSourceStatusEnum.NoType); } if (newListener.IsListeningForNewDC) { bool isListening = newListener.Subscribe(subscriber); System.Diagnostics.Debug.Assert(isListening, "Subscriber was already present, but should not have been."); isListening = newListener.IsListeningForNewDC; } this[index] = newListener; #if DEBUG bool hasType = newListener.GetHasTypeAndHasData(out bool hasData); #endif // The new path listener is ready to start monitoring Property and/or Collection Changed events if // it still has a reference to the object that will be monitored. return(newListener.Status); }