// --------------------- /// <summary> /// Creates an observation manager for the given key path. /// </summary> /// <param name="observedObj">The object to observe.</param> /// <param name="keyPath">The key path to observe.</param> /// <param name="observer">The observer.</param> /// <param name="options">Bitwise-Or of the desired observation objects.</param> /// <param name="context">The context of the observation. Used for comparison only.</param> public void AddObserverToKeyPathOfObject(Object observedObj, String keyPath, KNKVOObserver observer, KNKeyValueObservingOptions options, Object context) { if (keyPath.Contains('.')) { KNKVOKeyPathObserver observerProxy = new KNKVOKeyPathObserver(observedObj, keyPath, observer, options, context); keyPathObservations.Add(observerProxy); } else { KNKVOObservationInfo info = new KNKVOObservationInfo(keyPath, options, observer, observedObj, context); internalObservations.Add(info); } }
public KNKVOObservationInfo(String aKey, KNKeyValueObservingOptions someOptions, KNKVOObserver anObserver, Object anObservedObject, Object aContext) { changes = new Stack<KNKVOObservationChangeTracker>(); observedObjectReference = new WeakReference(anObservedObject); options = someOptions; observer = anObserver; key = aKey; context = aContext; // Get a helper object if needed if (anObservedObject != null) { helper = KNKVOCore.SharedCore().HelperForObject(anObservedObject); } // Check for coupled keys String keyPathsMethodName = "KeyPathsForValuesAffecting" + key.Substring(0, 1).ToUpper() + key.Substring(1); MethodInfo keyPathsMethod = observedObject.GetType().GetMethod(keyPathsMethodName, BindingFlags.Static | BindingFlags.Public); try { if (!(keyPathsMethod == null)) { String[] relatedKeys = (String[])keyPathsMethod.Invoke(observedObject, null); foreach (String relatedKey in relatedKeys) { observedObject.AddObserverToKeyPathWithOptions( this, relatedKey, KNKeyValueObservingOptions.KNKeyValueObservingOptionOld | KNKeyValueObservingOptions.KNKeyValueObservingOptionNew | KNKeyValueObservingOptions.KNKeyValueObservingOptionPrior, null); } keyPathsRelatedToObservation = relatedKeys; } } catch { // Silence! } // ---- if ((options & KNKeyValueObservingOptions.KNKeyValueObservingOptionInitial) == KNKeyValueObservingOptions.KNKeyValueObservingOptionInitial) { fireObservation(observedObject.ValueForKey(aKey), null, false); } }
public KNKVOKeyPathObserver(Object aBaseObject, String aKeyPath, KNKVOObserver anObserver, KNKeyValueObservingOptions someOptions, Object aContext) { changes = new Stack<KNKVOObservationChangeTracker>(); previousObservations = new ArrayList(); baseObjectRef = new WeakReference(aBaseObject); keyPath = aKeyPath; context = aContext; options = someOptions; observer = anObserver; //this.ObserveValueForKeyPathOfObject(aKeyPath, observedObject, null, context); ResetObservationTree(); if ((options & KNKeyValueObservingOptions.KNKeyValueObservingOptionInitial) == KNKeyValueObservingOptions.KNKeyValueObservingOptionInitial) { Dictionary<String, Object> change = new Dictionary<String, Object>(); if ((options & KNKeyValueObservingOptions.KNKeyValueObservingOptionNew) == KNKeyValueObservingOptions.KNKeyValueObservingOptionNew) { change.SetValueForKey(observedObject.ValueForKeyPath(keyPath), KNKVOConstants.KNKeyValueChangeNewKey); } observer.ObserveValueForKeyPathOfObject(keyPath, observedObject, change, context); } }
/// <summary> /// Removes an observer from the given key path of an object. /// </summary> /// <param name="observedObj">The observed object.</param> /// <param name="keyPath">The key path to remove the observed from.</param> /// <param name="observer">The observer to remove.</param> public void RemoveObserverFromKeyPathOfObject(Object observedObj, String keyPath, KNKVOObserver observer) { if (keyPath.Contains('.')) { ArrayList proxiesToRemove = new ArrayList(); foreach (KNKVOKeyPathObserver observerProxy in keyPathObservations) { if ((observerProxy.observedObject == observedObj) && (observerProxy.keyPath == keyPath) && (observerProxy.observer == observer)) { proxiesToRemove.Add(observerProxy); } } foreach (KNKVOKeyPathObserver observerProxy in proxiesToRemove) { keyPathObservations.Remove(observerProxy); observerProxy.Dispose(); } } else { ArrayList infoToRemove = new ArrayList(); foreach (KNKVOObservationInfo info in internalObservations) { if (info.key.Equals(keyPath) && (info.observedObject == observedObj) && (info.observer == observer)) { infoToRemove.Add(info); } } foreach (KNKVOObservationInfo info in infoToRemove) { info.Dispose(); internalObservations.Remove(info); } } }
/// <summary> /// Removes an observer from a KVO-compliant key path of the receiver. /// </summary> /// <param name="o">The object to remove the observation from.</param> /// <param name="observer">The observer to remove.</param> /// <param name="keyPath">The key path of the observation to remove.</param> public static void RemoveObserverFromKeyPath(this Object o, KNKVOObserver observer, String keyPath) { KNKVOCore.SharedCore().RemoveObserverFromKeyPathOfObject(o, keyPath, observer); }
/// <summary> /// Adds an observer to a KVO-compliant key path of the receiver. /// </summary> /// <param name="o">The object to be observed.</param> /// <param name="observer">The object to receive the change notifications.</param> /// <param name="keyPath">The key path to observe.</param> /// <param name="options">A bitwise-OR of the desired options. See the <c>KNKeyValueObservingOptions</c> enum for details.</param> /// <param name="context">A unique context to identify this observation.</param> /// <seealso cref="KNKeyValueObservingOptions"/> public static void AddObserverToKeyPathWithOptions(this Object o, KNKVOObserver observer, String keyPath, KNKeyValueObservingOptions options, Object context) { KNKVOCore.SharedCore().AddObserverToKeyPathOfObject(o, keyPath, observer, options, context); }