// Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using Avalonia.Data; namespace Avalonia { /// /// A registered binding in a . /// internal class PriorityBindingEntry : IDisposable { private PriorityLevel _owner; private IDisposable _subscription; /// /// Initializes a new instance of the class. /// /// The owner. /// /// The binding index. Later bindings should have higher indexes. /// public PriorityBindingEntry(PriorityLevel owner, int index) { _owner = owner; Index = index; } /// /// Gets the observable associated with the entry. /// public IObservable Observable { get; private set; } /// /// Gets a description of the binding. /// public string Description { get; private set; } /// /// Gets the binding entry index. Later bindings will have higher indexes. /// public int Index { get; } /// /// The current value of the binding. /// public object Value { get; private set; } /// /// Starts listening to the binding. /// /// The binding. public void Start(IObservable binding) { Contract.Requires(binding != null); if (_subscription != null) { throw new Exception("PriorityValue.Entry.Start() called more than once."); } Observable = binding; Value = AvaloniaProperty.UnsetValue; if (binding is IDescription) { Description = ((IDescription)binding).Description; } _subscription = binding.Subscribe(ValueChanged, Completed); } /// /// Ends the binding subscription. /// public void Dispose() { _subscription?.Dispose(); } private void ValueChanged(object value) { _owner.Owner.Owner?.VerifyAccess(); var notification = value as BindingNotification; if (notification != null) { if (notification.HasValue || notification.ErrorType == BindingErrorType.Error) { Value = notification.Value; _owner.Changed(this); } if (notification.ErrorType != BindingErrorType.None) { _owner.Error(this, notification); } } else { Value = value; _owner.Changed(this); } } private void Completed() { _owner.Completed(this); } } }