Browse Source

Use custom class for direct binding subscriptions.

pull/1690/head
Steven Kirk 8 years ago
parent
commit
b488ca179a
  1. 53
      src/Avalonia.Base/AvaloniaObject.cs

53
src/Avalonia.Base/AvaloniaObject.cs

@ -10,6 +10,7 @@ using System.Reactive.Linq;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Reactive;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -38,7 +39,7 @@ namespace Avalonia
/// Maintains a list of direct property binding subscriptions so that the binding source /// Maintains a list of direct property binding subscriptions so that the binding source
/// doesn't get collected. /// doesn't get collected.
/// </summary> /// </summary>
private List<IDisposable> _directBindings; private List<DirectBindingSubscription> _directBindings;
/// <summary> /// <summary>
/// Event handler for <see cref="INotifyPropertyChanged"/> implementation. /// Event handler for <see cref="INotifyPropertyChanged"/> implementation.
@ -359,25 +360,12 @@ namespace Avalonia
property, property,
description); description);
IDisposable subscription = null;
if (_directBindings == null) if (_directBindings == null)
{ {
_directBindings = new List<IDisposable>(); _directBindings = new List<DirectBindingSubscription>();
} }
subscription = source return new DirectBindingSubscription(this, property, source);
.Select(x => CastOrDefault(x, property.PropertyType))
.Do(_ => { }, () => _directBindings.Remove(subscription))
.Subscribe(x => SetDirectValue(property, x));
_directBindings.Add(subscription);
return Disposable.Create(() =>
{
subscription.Dispose();
_directBindings.Remove(subscription);
});
} }
else else
{ {
@ -908,5 +896,38 @@ namespace Avalonia
value, value,
priority); priority);
} }
private class DirectBindingSubscription : IObserver<object>, IDisposable
{
readonly AvaloniaObject _owner;
readonly AvaloniaProperty _property;
IDisposable _subscription;
public DirectBindingSubscription(
AvaloniaObject owner,
AvaloniaProperty property,
IObservable<object> source)
{
_owner = owner;
_property = property;
_owner._directBindings.Add(this);
_subscription = source.Subscribe(this);
}
public void Dispose()
{
_subscription.Dispose();
_owner._directBindings.Remove(this);
}
public void OnCompleted() => Dispose();
public void OnError(Exception error) => Dispose();
public void OnNext(object value)
{
var castValue = CastOrDefault(value, _property.PropertyType);
_owner.SetDirectValue(_property, castValue);
}
}
} }
} }

Loading…
Cancel
Save