PropertyAccessorBase.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using Avalonia.Data;
  5. namespace Avalonia.Markup.Data.Plugins
  6. {
  7. /// <summary>
  8. /// Defines a default base implementation for a <see cref="IPropertyAccessor"/>.
  9. /// </summary>
  10. /// <remarks>
  11. /// <see cref="IPropertyAccessor"/> is an observable that will only be subscribed to one time.
  12. /// In addition, the subscription can be disposed by calling <see cref="Dispose()"/> on the
  13. /// property accessor itself - this prevents needing to hold two references for a subscription.
  14. /// </remarks>
  15. public abstract class PropertyAccessorBase : IPropertyAccessor
  16. {
  17. /// <inheritdoc/>
  18. public abstract Type PropertyType { get; }
  19. /// <inheritdoc/>
  20. public abstract object Value { get; }
  21. /// <summary>
  22. /// Stops the subscription.
  23. /// </summary>
  24. public void Dispose() => Dispose(true);
  25. /// <inheritdoc/>
  26. public abstract bool SetValue(object value, BindingPriority priority);
  27. /// <summary>
  28. /// The currently subscribed observer.
  29. /// </summary>
  30. protected IObserver<object> Observer { get; private set; }
  31. /// <inheritdoc/>
  32. public IDisposable Subscribe(IObserver<object> observer)
  33. {
  34. Contract.Requires<ArgumentNullException>(observer != null);
  35. if (Observer != null)
  36. {
  37. throw new InvalidOperationException(
  38. "A property accessor can be subscribed to only once.");
  39. }
  40. Observer = observer;
  41. SubscribeCore(observer);
  42. return this;
  43. }
  44. /// <summary>
  45. /// Stops listening to the property.
  46. /// </summary>
  47. /// <param name="disposing">
  48. /// True if the <see cref="Dispose()"/> method was called, false if the object is being
  49. /// finalized.
  50. /// </param>
  51. protected virtual void Dispose(bool disposing) => Observer = null;
  52. /// <summary>
  53. /// When overridden in a derived class, begins listening to the property.
  54. /// </summary>
  55. protected abstract void SubscribeCore(IObserver<object> observer);
  56. }
  57. }