diff --git a/src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs b/src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs index 9c6556b809..56882ddcbe 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs @@ -27,10 +27,12 @@ namespace Avalonia.Markup.Xaml.Data /// Initializes a new instance of the class. /// /// The binding path. - public Binding(string path) + /// The binding mode. + public Binding(string path, BindingMode mode = BindingMode.Default) : this() { Path = path; + Mode = mode; } /// diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs index f128a67839..8759cb42c5 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Validation.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using Avalonia.Controls; using Avalonia.Data; using Avalonia.Markup.Xaml.Data; @@ -25,7 +26,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data } [Fact] - public void Validated_Property_Receives_BindingNotifications() + public void Validated_Direct_Property_Receives_BindingNotifications() { var source = new ValidationTestModel { MustBePositive = 5 }; var target = new TestControl @@ -33,119 +34,25 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data DataContext = source, }; - target.Bind(TestControl.ValidatedProperty, new Binding(nameof(source.MustBePositive))); - source.MustBePositive = 6; + target.Bind( + TestControl.ValidatedDirectProperty, + new Binding(nameof(source.MustBePositive), BindingMode.TwoWay)); + + target.ValidatedDirect = 6; + target.ValidatedDirect = -1; + target.ValidatedDirect = 7; Assert.Equal( new[] { new BindingNotification(5), - new BindingNotification(new ArgumentOutOfRangeException("value"), BindingErrorType.DataValidationError), new BindingNotification(6), + new BindingNotification(new ArgumentOutOfRangeException("value"), BindingErrorType.DataValidationError), + new BindingNotification(7), }, - target.Notifications); + target.Notifications.AsEnumerable()); } - //[Fact] - //public void Disabled_Validation_Should_Trigger_Validation_Change_On_Exception() - //{ - // var source = new ValidationTestModel { MustBePositive = 5 }; - // var target = new TestControl { DataContext = source }; - // var binding = new Binding - // { - // Path = nameof(source.MustBePositive), - // Mode = BindingMode.TwoWay, - - // // Even though EnableValidation = false, exception validation is enabled. - // EnableValidation = false, - // }; - - // target.Bind(TestControl.ValidationTestProperty, binding); - - // target.ValidationTest = -5; - - // Assert.True(false); - // //Assert.False(target.ValidationStatus.IsValid); - //} - - //[Fact] - //public void Enabled_Validation_Should_Trigger_Validation_Change_On_Exception() - //{ - // var source = new ValidationTestModel { MustBePositive = 5 }; - // var target = new TestControl { DataContext = source }; - // var binding = new Binding - // { - // Path = nameof(source.MustBePositive), - // Mode = BindingMode.TwoWay, - // EnableValidation = true, - // }; - - // target.Bind(TestControl.ValidationTestProperty, binding); - - // target.ValidationTest = -5; - // Assert.True(false); - // //Assert.False(target.ValidationStatus.IsValid); - //} - - - //[Fact] - //public void Passed_Validation_Should_Not_Add_Invalid_Pseudo_Class() - //{ - // var control = new TestControl(); - // var model = new ValidationTestModel { MustBePositive = 1 }; - // var binding = new Binding - // { - // Path = nameof(model.MustBePositive), - // Mode = BindingMode.TwoWay, - // EnableValidation = true, - // }; - - // control.Bind(TestControl.ValidationTestProperty, binding); - // control.DataContext = model; - // Assert.DoesNotContain(control.Classes, x => x == ":invalid"); - //} - - //[Fact] - //public void Failed_Validation_Should_Add_Invalid_Pseudo_Class() - //{ - // var control = new TestControl(); - // var model = new ValidationTestModel { MustBePositive = 1 }; - // var binding = new Binding - // { - // Path = nameof(model.MustBePositive), - // Mode = BindingMode.TwoWay, - // EnableValidation = true, - // }; - - // control.Bind(TestControl.ValidationTestProperty, binding); - // control.DataContext = model; - // control.ValidationTest = -5; - // Assert.Contains(control.Classes, x => x == ":invalid"); - //} - - //[Fact] - //public void Failed_Then_Passed_Validation_Should_Remove_Invalid_Pseudo_Class() - //{ - // var control = new TestControl(); - // var model = new ValidationTestModel { MustBePositive = 1 }; - - // var binding = new Binding - // { - // Path = nameof(model.MustBePositive), - // Mode = BindingMode.TwoWay, - // EnableValidation = true, - // }; - - // control.Bind(TestControl.ValidationTestProperty, binding); - // control.DataContext = model; - - - // control.ValidationTest = -5; - // Assert.Contains(control.Classes, x => x == ":invalid"); - // control.ValidationTest = 5; - // Assert.DoesNotContain(control.Classes, x => x == ":invalid"); - //} - private class TestControl : Control { public static readonly StyledProperty NonValidatedProperty = @@ -158,6 +65,15 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data nameof(Validated), enableDataValidation: true); + public static readonly DirectProperty ValidatedDirectProperty = + AvaloniaProperty.RegisterDirect( + nameof(Validated), + o => o.ValidatedDirect, + (o, v) => o.ValidatedDirect = v, + enableDataValidation: true); + + private int _direct; + public int NonValidated { get { return GetValue(NonValidatedProperty); } @@ -170,6 +86,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data set { SetValue(ValidatedProperty, value); } } + public int ValidatedDirect + { + get { return _direct; } + set { SetAndRaise(ValidatedDirectProperty, ref _direct, value); } + } + public IList Notifications { get; } = new List(); protected override void BindingNotificationReceived(AvaloniaProperty property, BindingNotification notification) @@ -180,11 +102,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data private class ValidationTestModel : NotifyingBase { - private int mustBePositive; + private int _mustBePositive; public int MustBePositive { - get { return mustBePositive; } + get { return _mustBePositive; } set { if (value <= 0) @@ -192,8 +114,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data throw new ArgumentOutOfRangeException(nameof(value)); } - mustBePositive = value; - RaisePropertyChanged(); + if (_mustBePositive != value) + { + _mustBePositive = value; + RaisePropertyChanged(); + } } } }