/// <summary> /// Initializes a new instance of the <see cref="DependencyPropertyListener" /> class. /// </summary> public DependencyPropertyListener(object source, string propertyToBind, IEventListener listener) { _listener = listener.ToWeakWrapper(); BindingOperations.SetBinding(this, ValueProperty, new BindingEx { Path = new PropertyPath(propertyToBind), Source = source, Mode = BindingMode.OneWay, #if !NETFX_CORE #if !WINDOWS_PHONE UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, #endif #if !WINDOWSCOMMON #if !WPF || !NET4 ValidatesOnNotifyDataErrors = false, #endif ValidatesOnDataErrors = false, ValidatesOnExceptions = false, NotifyOnValidationError = false, #endif #if WPF NotifyOnSourceUpdated = false, NotifyOnTargetUpdated = false #endif #endif }); }
public void Dispose() { var listener = _eventListener; var weakItem = _weakItem; if (listener != null && !weakItem.IsEmpty) { _eventListener = null; _weakItem = WeakEventListenerWrapper.Empty; listener.Remove(weakItem, _propertyName); } }
static WeakEventListenerWrapper() { Empty = default(WeakEventListenerWrapper); }
/// <summary> /// Occurs on add a listener. /// </summary> protected override bool OnAdd(WeakEventListenerWrapper weakItem, bool withUnsubscriber, out IDisposable unsubscriber) { unsubscriber = null; if (!ReferenceEquals(Listeners, Empty)) return false; var source = _sourceRef.Target; if (source == null) return false; var state = new object[] { this, weakItem, null }; string member = _eventInfo == null ? BindingContextMember : EventPrefix + _eventInfo.Name; ServiceProvider.AttachedValueProvider.AddOrUpdate(source, member, AddSourceEventDelegate, UpdateSourceEventDelegate, state); unsubscriber = (IDisposable)state[2]; return true; }
private void Update(WeakEventListenerWrapper newItem, string path) { var references = newItem.IsEmpty ? new KeyValuePair<WeakEventListenerWrapper, string>[_listeners.Length] : new KeyValuePair<WeakEventListenerWrapper, string>[_listeners.Length + 1]; int index = 0; for (int i = 0; i < _listeners.Length; i++) { var reference = _listeners[i]; if (reference.Key.EventListener.IsAlive) references[index++] = reference; } if (!newItem.IsEmpty) { references[index] = new KeyValuePair<WeakEventListenerWrapper, string>(newItem, path); index++; } else if (index == 0) { //Remove event from source, if no listeners. _listeners = Empty; var target = (INotifyPropertyChanged)_propertyChanged.Target; if (target != null) { target.PropertyChanged -= Handle; ServiceProvider.AttachedValueProvider.Clear(target, PropertyChangedMember); } return; } if (references.Length != index) Array.Resize(ref references, index); _listeners = references; }
private void Remove(WeakEventListenerWrapper weakItem) { lock (_propertyChanged) { for (int i = 0; i < _listeners.Length; i++) { if (ReferenceEquals(_listeners[i].Key.Source, weakItem.Source)) { _listeners[i] = new KeyValuePair<WeakEventListenerWrapper, string>(WeakEventListenerWrapper.Empty, string.Empty); Update(WeakEventListenerWrapper.Empty, null); return; } } } }
private IDisposable AddInternal(WeakEventListenerWrapper weakItem, string path) { lock (_propertyChanged) { //if value was removed from another thread if (ReferenceEquals(_listeners, Empty)) { var source = (INotifyPropertyChanged)_propertyChanged.Target; if (source != null) { var state = new object[] { this, weakItem, path, null }; ServiceProvider.AttachedValueProvider.AddOrUpdate(source, PropertyChangedMember, AddSourceEventDelegate, UpdateSourceEventDelegate, state); return (IDisposable)state[3]; } } else if (_listeners.Length == 0) _listeners = new[] { new KeyValuePair<WeakEventListenerWrapper, string>(weakItem, path) }; else Update(weakItem, path); } return new Unsubscriber(this, weakItem); }
public Unsubscriber(WeakPropertyChangedListener eventListener, WeakEventListenerWrapper weakItem) { _eventListener = eventListener; _weakItem = weakItem; }
public VisiblityObserver(View view, IEventListener handler) : base(view, true) { _listenerRef = handler.ToWeakWrapper(); _oldValue = view.Visibility; }
public SizeObserver(View view, IEventListener handler) : base(view, false) { _listenerRef = handler.ToWeakWrapper(); _height = view.Height; _width = view.Width; }
public Unsubscriber(WeakPropertyChangedListener eventListener, WeakEventListenerWrapper weakItem, string propertyName) { _eventListener = eventListener; _weakItem = weakItem; _propertyName = propertyName; }
private void Remove(WeakEventListenerWrapper weakItem, string propertyName) { lock (this) { for (int i = 0; i < _listeners.Length; i++) { var pair = _listeners[i]; if (!pair.Key.IsEmpty && pair.Value == propertyName && ReferenceEquals(pair.Key.Source, weakItem.Source)) { ++_removedSize; _listeners[i] = default(KeyValuePair<WeakEventListenerWrapper, string>); return; } } } }
private IDisposable AddInternal(WeakEventListenerWrapper weakItem, string path) { lock (this) { if (_listeners.Length == 0) { _listeners = new[] { new KeyValuePair<WeakEventListenerWrapper, string>(weakItem, path) }; _size = 1; _removedSize = 0; } else { if (_removedSize == 0) { if (_size == _listeners.Length) EventListenerList.EnsureCapacity(ref _listeners, _size, _size + 1); _listeners[_size++] = new KeyValuePair<WeakEventListenerWrapper, string>(weakItem, path); } else { for (int i = 0; i < _size; i++) { if (_listeners[i].Key.IsEmpty) { _listeners[i] = new KeyValuePair<WeakEventListenerWrapper, string>(weakItem, path); --_removedSize; break; } } } } } return new Unsubscriber(this, weakItem, path); }