From ca7584ce3fef1ba5f8a7e8b7bb916dc4617a1f21 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 17 Oct 2017 23:45:00 +0200 Subject: [PATCH 1/2] Added failing test for #1218 --- .../Avalonia.Styling.UnitTests/SetterTests.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/Avalonia.Styling.UnitTests/SetterTests.cs b/tests/Avalonia.Styling.UnitTests/SetterTests.cs index 84536fa47b..9c43097a21 100644 --- a/tests/Avalonia.Styling.UnitTests/SetterTests.cs +++ b/tests/Avalonia.Styling.UnitTests/SetterTests.cs @@ -8,6 +8,9 @@ using Avalonia.Data; using Xunit; using System; using Avalonia.Controls.Templates; +using Avalonia.Markup.Xaml.Data; +using Avalonia.Markup; +using System.Globalization; namespace Avalonia.Styling.UnitTests { @@ -61,5 +64,39 @@ namespace Avalonia.Styling.UnitTests Assert.NotNull(NameScope.GetNameScope((Control)control.Child)); } + + [Fact] + public void Does_Not_Call_Converter_ConvertBack_On_OneWay_Binding() + { + var control = new Decorator { Name = "foo" }; + var style = Mock.Of(); + var binding = new Binding("Name", BindingMode.OneWay) + { + Converter = new TestConverter(), + RelativeSource = new RelativeSource(RelativeSourceMode.Self), + }; + var setter = new Setter(Decorator.TagProperty, binding); + var activator = new BehaviorSubject(true); + + setter.Apply(style, control, activator); + Assert.Equal("foobar", control.Tag); + + // Issue #1218 caused TestConverter.ConvertBack to throw here. + activator.OnNext(false); + Assert.Null(control.Tag); + } + + private class TestConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value.ToString() + "bar"; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } } } From dede306531fc38eef26807cd0eb028f9dbd66470 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 17 Oct 2017 23:45:35 +0200 Subject: [PATCH 2/2] Fixed #1218 --- src/Avalonia.Styling/Styling/Setter.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Styling/Styling/Setter.cs b/src/Avalonia.Styling/Styling/Setter.cs index d065b231ce..eb5218cd6f 100644 --- a/src/Avalonia.Styling/Styling/Setter.cs +++ b/src/Avalonia.Styling/Styling/Setter.cs @@ -141,20 +141,20 @@ namespace Avalonia.Styling { var description = style?.ToString(); - if (sourceInstance.Subject != null) + if (sourceInstance.Mode == BindingMode.TwoWay || sourceInstance.Mode == BindingMode.OneWayToSource) { var activated = new ActivatedSubject(activator, sourceInstance.Subject, description); cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); } - else if (sourceInstance.Observable != null) + else if (sourceInstance.Mode == BindingMode.OneTime) { - var activated = new ActivatedObservable(activator, sourceInstance.Observable, description); - cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); + var activated = new ActivatedValue(activator, sourceInstance.Value, description); + cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger); } else { - var activated = new ActivatedValue(activator, sourceInstance.Value, description); - cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger); + var activated = new ActivatedObservable(activator, sourceInstance.Observable ?? sourceInstance.Subject, description); + cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); } } else