PropertyAccessorNode.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 System.Linq;
  5. using System.Reactive.Linq;
  6. using Avalonia.Data.Core.Plugins;
  7. namespace Avalonia.Data.Core
  8. {
  9. public class PropertyAccessorNode : SettableNode
  10. {
  11. private readonly bool _enableValidation;
  12. private IPropertyAccessor _accessor;
  13. public PropertyAccessorNode(string propertyName, bool enableValidation)
  14. {
  15. PropertyName = propertyName;
  16. _enableValidation = enableValidation;
  17. }
  18. public override string Description => PropertyName;
  19. public string PropertyName { get; }
  20. public override Type PropertyType => _accessor?.PropertyType;
  21. protected override bool SetTargetValueCore(object value, BindingPriority priority)
  22. {
  23. if (_accessor != null)
  24. {
  25. try
  26. {
  27. return _accessor.SetValue(value, priority);
  28. }
  29. catch { }
  30. }
  31. return false;
  32. }
  33. protected override void StartListeningCore(WeakReference reference)
  34. {
  35. var plugin = ExpressionObserver.PropertyAccessors.FirstOrDefault(x => x.Match(reference.Target, PropertyName));
  36. var accessor = plugin?.Start(reference, PropertyName);
  37. if (_enableValidation && Next == null)
  38. {
  39. foreach (var validator in ExpressionObserver.DataValidators)
  40. {
  41. if (validator.Match(reference, PropertyName))
  42. {
  43. accessor = validator.Start(reference, PropertyName, accessor);
  44. }
  45. }
  46. }
  47. if (accessor == null)
  48. {
  49. throw new NotSupportedException(
  50. $"Could not find a matching property accessor for {PropertyName}.");
  51. }
  52. accessor.Subscribe(ValueChanged);
  53. _accessor = accessor;
  54. }
  55. protected override void StopListeningCore()
  56. {
  57. _accessor.Dispose();
  58. _accessor = null;
  59. }
  60. }
  61. }