diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs index 71e6b9474f..75e56c7186 100644 --- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs +++ b/src/Avalonia.Base/AvaloniaObjectExtensions.cs @@ -36,6 +36,9 @@ namespace Avalonia /// An observable which fires immediately with the current value of the property on the /// object and subsequently each time the property value changes. /// + /// + /// The subscription to is created using a weak reference. + /// public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaProperty property) { Contract.Requires(o != null); @@ -54,6 +57,9 @@ namespace Avalonia /// An observable which fires immediately with the current value of the property on the /// object and subsequently each time the property value changes. /// + /// + /// The subscription to is created using a weak reference. + /// public static IObservable GetObservable(this IAvaloniaObject o, AvaloniaProperty property) { Contract.Requires(o != null); @@ -130,23 +136,6 @@ namespace Avalonia o.GetObservable(property)); } - /// - /// Gets a weak observable for a . - /// - /// The object. - /// The property. - /// An observable. - public static IObservable GetWeakObservable(this IAvaloniaObject o, AvaloniaProperty property) - { - Contract.Requires(o != null); - Contract.Requires(property != null); - - return new WeakPropertyChangedObservable( - new WeakReference(o), - property, - GetDescription(o, property)); - } - /// /// Binds a property on an to an . /// diff --git a/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs index 8cbcaa8233..48edb218dc 100644 --- a/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs +++ b/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs @@ -153,7 +153,7 @@ namespace Avalonia.Data.Core.Plugins protected override void SubscribeCore(IObserver observer) { - _subscription = Instance?.GetWeakObservable(_property).Subscribe(observer); + _subscription = Instance?.GetObservable(_property).Subscribe(observer); } } } diff --git a/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs b/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs index c19423b623..0e07065d6c 100644 --- a/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs +++ b/src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs @@ -1,10 +1,11 @@ using System; +using Avalonia.Utilities; namespace Avalonia.Reactive { public class AvaloniaPropertyObservable : LightweightObservableBase, IDescription { - private readonly IAvaloniaObject _target; + private readonly WeakReference _target; private readonly AvaloniaProperty _property; private T _value; @@ -12,7 +13,7 @@ namespace Avalonia.Reactive IAvaloniaObject target, AvaloniaProperty property) { - _target = target; + _target = new WeakReference(target); _property = property; } @@ -20,13 +21,19 @@ namespace Avalonia.Reactive protected override void Initialize() { - _value = (T)_target.GetValue(_property); - _target.PropertyChanged += PropertyChanged; + if (_target.TryGetTarget(out var target)) + { + _value = (T)target.GetValue(_property); + target.PropertyChanged += PropertyChanged; + } } protected override void Deinitialize() { - _target.PropertyChanged -= PropertyChanged; + if (_target.TryGetTarget(out var target)) + { + target.PropertyChanged -= PropertyChanged; + } } protected override void Subscribed(IObserver observer, bool first) diff --git a/src/Avalonia.Base/Reactive/WeakPropertyChangedObservable.cs b/src/Avalonia.Base/Reactive/WeakPropertyChangedObservable.cs deleted file mode 100644 index aa5f553865..0000000000 --- a/src/Avalonia.Base/Reactive/WeakPropertyChangedObservable.cs +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Reactive; -using System.Reactive.Disposables; -using System.Reactive.Linq; -using System.Reactive.Subjects; -using Avalonia.Utilities; - -namespace Avalonia.Reactive -{ - internal class WeakPropertyChangedObservable : ObservableBase, - IWeakSubscriber, IDescription - { - private WeakReference _sourceReference; - private readonly AvaloniaProperty _property; - private readonly Subject _changed = new Subject(); - - private int _count; - - public WeakPropertyChangedObservable( - WeakReference source, - AvaloniaProperty property, - string description) - { - _sourceReference = source; - _property = property; - Description = description; - } - - public string Description { get; } - - public void OnEvent(object sender, AvaloniaPropertyChangedEventArgs e) - { - if (e.Property == _property) - { - _changed.OnNext(e.NewValue); - } - } - - protected override IDisposable SubscribeCore(IObserver observer) - { - IAvaloniaObject instance; - - if (_sourceReference.TryGetTarget(out instance)) - { - if (_count++ == 0) - { - WeakSubscriptionManager.Subscribe( - instance, - nameof(instance.PropertyChanged), - this); - } - - observer.OnNext(instance.GetValue(_property)); - - return Observable.Using(() => Disposable.Create(DecrementCount), _ => _changed) - .Subscribe(observer); - } - else - { - _changed.OnCompleted(); - observer.OnCompleted(); - return Disposable.Empty; - } - } - - private void DecrementCount() - { - if (--_count == 0) - { - IAvaloniaObject instance; - - if (_sourceReference.TryGetTarget(out instance)) - { - WeakSubscriptionManager.Unsubscribe( - instance, - nameof(instance.PropertyChanged), - this); - } - } - } - } -}