diff --git a/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs b/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs index 3c4120ad0b..cc6d92ceb7 100644 --- a/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs +++ b/src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.ExceptionServices; +using Avalonia.Utilities; namespace Avalonia.Data.Core.Plugins { @@ -60,11 +61,10 @@ namespace Avalonia.Data.Core.Plugins return AvaloniaPropertyRegistry.Instance.FindRegistered(o, propertyName); } - private class Accessor : PropertyAccessorBase, IObserver + private class Accessor : PropertyAccessorBase, IWeakEventSubscriber { private readonly WeakReference _reference; private readonly AvaloniaProperty _property; - private IDisposable? _subscription; public Accessor(WeakReference reference, AvaloniaProperty property) { @@ -95,29 +95,45 @@ namespace Avalonia.Data.Core.Plugins return false; } - protected override void SubscribeCore() + void IWeakEventSubscriber. + OnEvent(object? notifyPropertyChanged, WeakEvent ev, AvaloniaPropertyChangedEventArgs e) { - _subscription = Instance?.GetObservable(_property).Subscribe(this); + if (e.Property == _property) + { + SendCurrentValue(); + } } - protected override void UnsubscribeCore() + protected override void SubscribeCore() { - _subscription?.Dispose(); - _subscription = null; + SubscribeToChanges(); + SendCurrentValue(); } - void IObserver.OnCompleted() + protected override void UnsubscribeCore() { + var instance = Instance; + + if (instance != null) + WeakEvents.AvaloniaPropertyChanged.Unsubscribe(instance, this); } - void IObserver.OnError(Exception error) + private void SendCurrentValue() { - ExceptionDispatchInfo.Capture(error).Throw(); + try + { + var value = Value; + PublishValue(value); + } + catch { } } - void IObserver.OnNext(object? value) + private void SubscribeToChanges() { - PublishValue(value); + var instance = Instance; + + if (instance != null) + WeakEvents.AvaloniaPropertyChanged.Subscribe(instance, this); } } } diff --git a/src/Avalonia.Base/Utilities/WeakEvents.cs b/src/Avalonia.Base/Utilities/WeakEvents.cs index d1b5e7f12d..6da899bab2 100644 --- a/src/Avalonia.Base/Utilities/WeakEvents.cs +++ b/src/Avalonia.Base/Utilities/WeakEvents.cs @@ -31,10 +31,23 @@ public class WeakEvents return () => s.PropertyChanged -= handler; }); + + /// + /// Represents PropertyChanged event from + /// + public static readonly WeakEvent + AvaloniaPropertyChanged = WeakEvent.Register( + (s, h) => + { + EventHandler handler = (_, e) => h(s, e); + s.PropertyChanged += handler; + return () => s.PropertyChanged -= handler; + }); + /// /// Represents CanExecuteChanged event from /// public static readonly WeakEvent CommandCanExecuteChanged = WeakEvent.Register((s, h) => s.CanExecuteChanged += h, (s, h) => s.CanExecuteChanged -= h); -} \ No newline at end of file +}