A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

120 lines
3.2 KiB

using System;
using Avalonia.Data;
using Avalonia.Reactive;
#nullable enable
namespace Avalonia.Styling
{
/// <summary>
/// A <see cref="Setter"/> which has been instanced on a control.
/// </summary>
/// <typeparam name="T">The target property type.</typeparam>
internal class PropertySetterInstance<T> : SingleSubscriberObservableBase<BindingValue<T>>,
ISetterInstance
{
private readonly IStyleable _target;
private readonly StyledPropertyBase<T>? _styledProperty;
private readonly DirectPropertyBase<T>? _directProperty;
private readonly T _value;
private IDisposable? _subscription;
private bool _isActive;
public PropertySetterInstance(
IStyleable target,
StyledPropertyBase<T> property,
T value)
{
_target = target;
_styledProperty = property;
_value = value;
}
public PropertySetterInstance(
IStyleable target,
DirectPropertyBase<T> property,
T value)
{
_target = target;
_directProperty = property;
_value = value;
}
public void Start(bool hasActivator)
{
if (hasActivator)
{
if (_styledProperty is not null)
{
_subscription = _target.Bind(_styledProperty, this, BindingPriority.StyleTrigger);
}
else
{
_subscription = _target.Bind(_directProperty!, this);
}
}
else
{
var target = (AvaloniaObject) _target;
if (_styledProperty is not null)
{
_subscription = target.SetValue(_styledProperty!, _value, BindingPriority.Style);
}
else
{
target.SetValue(_directProperty!, _value);
}
}
}
public void Activate()
{
if (!_isActive)
{
_isActive = true;
PublishNext();
}
}
public void Deactivate()
{
if (_isActive)
{
_isActive = false;
PublishNext();
}
}
public override void Dispose()
{
if (_subscription is object)
{
var sub = _subscription;
_subscription = null;
sub.Dispose();
}
else if (_isActive)
{
if (_styledProperty is object)
{
_target.ClearValue(_styledProperty);
}
else
{
_target.ClearValue(_directProperty!);
}
}
base.Dispose();
}
protected override void Subscribed() => PublishNext();
protected override void Unsubscribed() { }
private void PublishNext()
{
PublishNext(_isActive ? new BindingValue<T>(_value) : default);
}
}
}