Browse Source

Make SingleSubscriberObservableBase internal.

The last public dependency was `TemplateBinding` which can trivially be made to not inherit from it.
pull/11556/head
Steven Kirk 3 years ago
parent
commit
d198bad34b
  1. 37
      src/Avalonia.Base/Data/TemplateBinding.cs
  2. 2
      src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs

37
src/Avalonia.Base/Data/TemplateBinding.cs

@ -3,18 +3,21 @@ using System.Globalization;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Reactive; using Avalonia.Reactive;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.Threading;
namespace Avalonia.Data namespace Avalonia.Data
{ {
/// <summary> /// <summary>
/// A XAML binding to a property on a control's templated parent. /// A XAML binding to a property on a control's templated parent.
/// </summary> /// </summary>
public class TemplateBinding : SingleSubscriberObservableBase<object?>, public class TemplateBinding : IObservable<object?>,
IBinding, IBinding,
IDescription, IDescription,
IAvaloniaSubject<object?>, IAvaloniaSubject<object?>,
ISetterValue ISetterValue,
IDisposable
{ {
private IObserver<object?>? _observer;
private bool _isSetterValue; private bool _isSetterValue;
private StyledElement? _target; private StyledElement? _target;
private Type? _targetType; private Type? _targetType;
@ -29,6 +32,28 @@ namespace Avalonia.Data
Property = property; Property = property;
} }
public IDisposable Subscribe(IObserver<object?> observer)
{
_ = observer ?? throw new ArgumentNullException(nameof(observer));
Dispatcher.UIThread.VerifyAccess();
if (_observer != null)
{
throw new InvalidOperationException("The observable can only be subscribed once.");
}
_observer = observer;
Subscribed();
return this;
}
public virtual void Dispose()
{
Unsubscribed();
_observer = null;
}
/// <inheritdoc/> /// <inheritdoc/>
public InstancedBinding? Initiate( public InstancedBinding? Initiate(
AvaloniaObject target, AvaloniaObject target,
@ -111,7 +136,7 @@ namespace Avalonia.Data
/// <inheritdoc/> /// <inheritdoc/>
void ISetterValue.Initialize(SetterBase setter) => _isSetterValue = true; void ISetterValue.Initialize(SetterBase setter) => _isSetterValue = true;
protected override void Subscribed() private void Subscribed()
{ {
TemplatedParentChanged(); TemplatedParentChanged();
@ -121,7 +146,7 @@ namespace Avalonia.Data
} }
} }
protected override void Unsubscribed() private void Unsubscribed()
{ {
if (_target?.TemplatedParent is { } templatedParent) if (_target?.TemplatedParent is { } templatedParent)
{ {
@ -147,12 +172,12 @@ namespace Avalonia.Data
value = Converter.Convert(value, _targetType ?? typeof(object), ConverterParameter, CultureInfo.CurrentCulture); value = Converter.Convert(value, _targetType ?? typeof(object), ConverterParameter, CultureInfo.CurrentCulture);
} }
PublishNext(value); _observer?.OnNext(value);
_hasProducedValue = true; _hasProducedValue = true;
} }
else if (_hasProducedValue) else if (_hasProducedValue)
{ {
PublishNext(AvaloniaProperty.UnsetValue); _observer?.OnNext(AvaloniaProperty.UnsetValue);
_hasProducedValue = false; _hasProducedValue = false;
} }
} }

2
src/Avalonia.Base/Reactive/SingleSubscriberObservableBase.cs

@ -3,7 +3,7 @@ using Avalonia.Threading;
namespace Avalonia.Reactive namespace Avalonia.Reactive
{ {
public abstract class SingleSubscriberObservableBase<T> : IObservable<T>, IDisposable internal abstract class SingleSubscriberObservableBase<T> : IObservable<T>, IDisposable
{ {
private Exception? _error; private Exception? _error;
private IObserver<T>? _observer; private IObserver<T>? _observer;

Loading…
Cancel
Save