BindingTests_Validation.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Avalonia.Controls;
  6. using Avalonia.Data;
  7. using Avalonia.Markup.Xaml.Data;
  8. using Avalonia.UnitTests;
  9. using Xunit;
  10. namespace Avalonia.Markup.Xaml.UnitTests.Data
  11. {
  12. public class BindingTests_Validation
  13. {
  14. [Fact]
  15. public void Non_Validated_Property_Does_Not_Receive_BindingNotifications()
  16. {
  17. var source = new ValidationTestModel { MustBePositive = 5 };
  18. var target = new TestControl
  19. {
  20. DataContext = source,
  21. [!TestControl.NonValidatedProperty] = new Binding(nameof(source.MustBePositive)),
  22. };
  23. Assert.Empty(target.Notifications);
  24. }
  25. [Fact]
  26. public void Validated_Direct_Property_Receives_BindingNotifications()
  27. {
  28. var source = new ValidationTestModel { MustBePositive = 5 };
  29. var target = new TestControl
  30. {
  31. DataContext = source,
  32. };
  33. target.Bind(
  34. TestControl.ValidatedDirectProperty,
  35. new Binding(nameof(source.MustBePositive), BindingMode.TwoWay));
  36. target.ValidatedDirect = 6;
  37. target.ValidatedDirect = -1;
  38. target.ValidatedDirect = 7;
  39. Assert.Equal(
  40. new[]
  41. {
  42. null, // 5
  43. null, // 6
  44. new BindingNotification(new ArgumentOutOfRangeException("value"), BindingErrorType.DataValidationError),
  45. null, // 7
  46. },
  47. target.Notifications.AsEnumerable());
  48. }
  49. private class TestControl : Control
  50. {
  51. public static readonly StyledProperty<int> NonValidatedProperty =
  52. AvaloniaProperty.Register<TestControl, int>(
  53. nameof(Validated),
  54. enableDataValidation: false);
  55. public static readonly StyledProperty<int> ValidatedProperty =
  56. AvaloniaProperty.Register<TestControl, int>(
  57. nameof(Validated),
  58. enableDataValidation: true);
  59. public static readonly DirectProperty<TestControl, int> ValidatedDirectProperty =
  60. AvaloniaProperty.RegisterDirect<TestControl, int>(
  61. nameof(Validated),
  62. o => o.ValidatedDirect,
  63. (o, v) => o.ValidatedDirect = v,
  64. enableDataValidation: true);
  65. private int _direct;
  66. public int NonValidated
  67. {
  68. get { return GetValue(NonValidatedProperty); }
  69. set { SetValue(NonValidatedProperty, value); }
  70. }
  71. public int Validated
  72. {
  73. get { return GetValue(ValidatedProperty); }
  74. set { SetValue(ValidatedProperty, value); }
  75. }
  76. public int ValidatedDirect
  77. {
  78. get { return _direct; }
  79. set { SetAndRaise(ValidatedDirectProperty, ref _direct, value); }
  80. }
  81. public IList<BindingNotification> Notifications { get; } = new List<BindingNotification>();
  82. protected override void UpdateDataValidation(AvaloniaProperty property, BindingNotification notification)
  83. {
  84. Notifications.Add(notification);
  85. }
  86. }
  87. private class ValidationTestModel : NotifyingBase
  88. {
  89. private int _mustBePositive;
  90. public int MustBePositive
  91. {
  92. get { return _mustBePositive; }
  93. set
  94. {
  95. if (value <= 0)
  96. {
  97. throw new ArgumentOutOfRangeException(nameof(value));
  98. }
  99. if (_mustBePositive != value)
  100. {
  101. _mustBePositive = value;
  102. RaisePropertyChanged();
  103. }
  104. }
  105. }
  106. }
  107. }
  108. }