/// <summary> /// Called when the <see cref="Behavior{T}"/> is about to detach from the /// <see cref="Behavior{T}.AssociatedObject"/>. /// </summary> /// <remarks> /// When this method is called, detaching can not be canceled. The /// <see cref="Behavior{T}.AssociatedObject"/> is still set. /// </remarks> protected override void OnDetaching() { if (_propertyObserver != null) { _propertyObserver.Dispose(); _propertyObserver = null; } base.OnDetaching(); }
//-------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="ReflectedProperty"/> class. /// </summary> /// <param name="instance">The object instance.</param> /// <param name="property">The property.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="instance"/> or <paramref name="property"/> is <see langword="null"/>. /// </exception> public ReflectedProperty(object instance, PropertyDescriptor property) { if (instance == null) throw new ArgumentNullException(nameof(instance)); if (property == null) throw new ArgumentNullException(nameof(property)); Instance = instance; Descriptor = property; _bindablePropertyObserver = new BindablePropertyObserver(instance, property.Name); _bindablePropertyObserver.ValueChanged += OnValueChanged; }
/// <summary> /// Called after the behavior is attached to an <see cref="Behavior{T}.AssociatedObject"/>. /// </summary> /// <remarks> /// Override this to hook up functionality to the /// <see cref="Behavior{T}.AssociatedObject"/>. /// </remarks> protected override void OnAttached() { base.OnAttached(); var commandSource = AssociatedObject as ICommandSource; if (commandSource == null) { return; } _propertyObserver = new BindablePropertyObserver(AssociatedObject, "CommandParameter"); _propertyObserver.ValueChanged += OnCommandParameterChanged; }
//-------------------------------------------------------------- #region Creation & Cleanup //-------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="ReflectedProperty"/> class. /// </summary> /// <param name="instance">The object instance.</param> /// <param name="property">The property.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="instance"/> or <paramref name="property"/> is <see langword="null"/>. /// </exception> public ReflectedProperty(object instance, PropertyDescriptor property) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (property == null) { throw new ArgumentNullException(nameof(property)); } Instance = instance; Descriptor = property; _bindablePropertyObserver = new BindablePropertyObserver(instance, property.Name); _bindablePropertyObserver.ValueChanged += OnValueChanged; }
public void GarbageCollection() { var source = new Slider(); //var source = new Foo(); var sourceWeak = new WeakReference(source); var observer = new Foo(); var observerWeak = new WeakReference(observer); var bpo = new BindablePropertyObserver(source, "Value"); bpo.ValueChanged += observer.OnObservedValueChanged; //var pd = TypeDescriptor.GetProperties(typeof(Foo)).OfType<PropertyDescriptor>().First(d => d.Name == "Value"); //pd.AddValueChanged(source, observer.OnObservedValueChanged); Assert.That(observer.Value, Is.EqualTo(0)); source.Value = 1; Assert.That(observer.Value, Is.EqualTo(1)); source.Value = 2; Assert.That(observer.Value, Is.EqualTo(2)); Assert.IsTrue(sourceWeak.IsAlive); Assert.IsTrue(observerWeak.IsAlive); source = null; GC.Collect(); Assert.IsFalse(sourceWeak.IsAlive); // This works for DependencyObjects but not for normal CLR objects with INotifyPropertyChanged; Assert.IsTrue(observerWeak.IsAlive); observer = null; bpo = null; GC.Collect(); Assert.IsFalse(sourceWeak.IsAlive); Assert.IsFalse(observerWeak.IsAlive); }