Browse Source

Remove hack from PropertySetterBindingInstance.

pull/8600/head
Steven Kirk 4 years ago
parent
commit
6a667f5d56
  1. 29
      src/Avalonia.Base/PropertyStore/BindingEntry.cs
  2. 33
      src/Avalonia.Base/Styling/PropertySetterBindingInstance.cs

29
src/Avalonia.Base/PropertyStore/BindingEntry.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Data; using Avalonia.Data;
@ -10,7 +9,6 @@ namespace Avalonia.PropertyStore
IDisposable IDisposable
{ {
private readonly ValueFrame _frame; private readonly ValueFrame _frame;
private readonly IObservable<object?> _source;
private IDisposable? _subscription; private IDisposable? _subscription;
private bool _hasValue; private bool _hasValue;
private object? _value; private object? _value;
@ -21,7 +19,7 @@ namespace Avalonia.PropertyStore
IObservable<object?> source) IObservable<object?> source)
{ {
_frame = frame; _frame = frame;
_source = source; Source = source;
Property = property; Property = property;
} }
@ -35,6 +33,7 @@ namespace Avalonia.PropertyStore
} }
public AvaloniaProperty Property { get; } public AvaloniaProperty Property { get; }
protected IObservable<object?> Source { get; }
public void Dispose() public void Dispose()
{ {
@ -69,6 +68,18 @@ namespace Avalonia.PropertyStore
_subscription = null; _subscription = null;
} }
protected virtual void Start(bool produceValue)
{
if (_subscription is not null)
return;
// Will only produce a new value when subscription isn't null.
if (produceValue)
_subscription = Disposable.Empty;
_subscription = Source.Subscribe(this);
}
private void ClearValue() private void ClearValue()
{ {
if (_hasValue) if (_hasValue)
@ -123,17 +134,5 @@ namespace Avalonia.PropertyStore
_subscription = null; _subscription = null;
_frame.OnBindingCompleted(this); _frame.OnBindingCompleted(this);
} }
private void Start(bool produceValue)
{
if (_subscription is not null)
return;
// Will only produce a new value when subscription isn't null.
if (produceValue)
_subscription = Disposable.Empty;
_subscription = _source.Subscribe(this);
}
} }
} }

33
src/Avalonia.Base/Styling/PropertySetterBindingInstance.cs

@ -7,7 +7,9 @@ namespace Avalonia.Styling
{ {
internal class PropertySetterBindingInstance : BindingEntry, ISetterInstance internal class PropertySetterBindingInstance : BindingEntry, ISetterInstance
{ {
private readonly IDisposable? _twoWaySubscription; private readonly AvaloniaObject _target;
private readonly BindingMode _mode;
private IDisposable? _twoWaySubscription;
public PropertySetterBindingInstance( public PropertySetterBindingInstance(
AvaloniaObject target, AvaloniaObject target,
@ -17,18 +19,14 @@ namespace Avalonia.Styling
IObservable<object?> source) IObservable<object?> source)
: base(instance, property, source) : base(instance, property, source)
{ {
if (mode == BindingMode.TwoWay) _target = target;
_mode = mode;
if (mode == BindingMode.TwoWay &&
source is not IObserver<object?>)
{ {
// TODO: HUGE HACK FIXME throw new NotSupportedException(
if (source is IObserver<object?> observer) "Attempting to bind two-way with a binding source which doesn't support it.");
{
_twoWaySubscription = target.GetObservable(property).Skip(1).Subscribe(observer);
}
else
{
throw new NotSupportedException(
"Attempting to bind two-way with a binding source which doesn't support it.");
}
} }
} }
@ -37,5 +35,16 @@ namespace Avalonia.Styling
_twoWaySubscription?.Dispose(); _twoWaySubscription?.Dispose();
base.Unsubscribe(); base.Unsubscribe();
} }
protected override void Start(bool produceValue)
{
if (_mode == BindingMode.TwoWay)
{
var observer = (IObserver<object?>)Source;
_twoWaySubscription = _target.GetObservable(Property).Skip(1).Subscribe(observer);
}
base.Start(produceValue);
}
} }
} }

Loading…
Cancel
Save