[C] support TargetNullValue in TypedBindings (#4490)
authorStephane Delcroix <stephane@delcroix.org>
Wed, 21 Nov 2018 07:32:32 +0000 (08:32 +0100)
committerGitHub <noreply@github.com>
Wed, 21 Nov 2018 07:32:32 +0000 (08:32 +0100)
Call base.GetSourceValue so the TargetNullValue is returned in case of a
null value. I have no idea why the code was there, but commented out,
and I don't want any of you to start digging at the why it wasn't
enabled before.

- fixes #4103

Xamarin.Forms.Core.UnitTests/TypedBindingUnitTests.cs
Xamarin.Forms.Core/TypedBinding.cs
Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml [new file with mode: 0644]
Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml.cs [new file with mode: 0644]

index be7415c..e1683ad 100644 (file)
@@ -1004,6 +1004,22 @@ namespace Xamarin.Forms.Core.UnitTests
                }
 
                [Test]
+               //https://github.com/xamarin/Xamarin.Forms/issues/4103
+               public void TestTargetNullValue()
+               {
+                       var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), default(string));
+                       var binding = new TypedBinding<MockViewModel, string>(vm => vm.Text, null, null) { TargetNullValue = "target null"};
+                       var bindable = new MockBindable();
+                       bindable.SetBinding(property, binding);
+                       bindable.BindingContext = new MockViewModel("initial");
+                       Assert.That(bindable.GetValue(property), Is.EqualTo("initial"));
+
+                       bindable.BindingContext = new MockViewModel(null);
+                       Assert.That(bindable.GetValue(property), Is.EqualTo("target null"));
+
+               }
+
+               [Test]
                [Description("OneWay bindings should not double apply on source updates.")]
                public void OneWayBindingsDontDoubleApplyOnSourceUpdates()
                {
index e27220b..185590f 100644 (file)
@@ -148,11 +148,7 @@ namespace Xamarin.Forms.Internals
                        if (Converter != null)
                                value = Converter.Convert(value, targetPropertyType, ConverterParameter, CultureInfo.CurrentUICulture);
 
-                       //return base.GetSourceValue(value, targetPropertyType);
-                       if (StringFormat != null)
-                               return string.Format(StringFormat, value);
-
-                       return value;
+                       return base.GetSourceValue(value, targetPropertyType);
                }
 
                internal override object GetTargetValue(object value, Type sourcePropertyType)
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml
new file mode 100644 (file)
index 0000000..9662725
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ContentPage
+               xmlns="http://xamarin.com/schemas/2014/forms"
+               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+               xmlns:local="using:Xamarin.Forms.Xaml.UnitTests"
+               x:Class="Xamarin.Forms.Xaml.UnitTests.Gh4103"
+               x:DataType="local:Gh4103VM">
+       <Label x:Name="label" Text="{Binding SomeNullableValue, TargetNullValue='target null', FallbackValue='fallback'}"/>
+</ContentPage>
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh4103.xaml.cs
new file mode 100644 (file)
index 0000000..9b66d13
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Xamarin.Forms;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+       public class Gh4103VM
+       {
+               public string SomeNullableValue { get; set; } = "initial";
+       }
+       public partial class Gh4103 : ContentPage
+       {
+               private string _someNullableValue = "initial";
+
+               public Gh4103()
+               {
+                       InitializeComponent();
+               }
+
+               public Gh4103(bool useCompiledXaml)
+               {
+                       //this stub will be replaced at compile time
+               }
+
+               [TestFixture]
+               class Tests
+               {
+                       [SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
+                       [TearDown] public void TearDown() => Device.PlatformServices = null;
+
+                       [TestCase(true), TestCase(false)]
+                       public void CompiledBindingsTargetNullValue(bool useCompiledXaml)
+                       {
+                               var layout = new Gh4103(useCompiledXaml) { BindingContext = new Gh4103VM() };
+                               Assert.That(layout.label.Text, Is.EqualTo("initial"));
+
+                               layout.BindingContext = new Gh4103VM { SomeNullableValue = null };
+                               Assert.That(layout.label.Text, Is.EqualTo("target null"));
+                       }
+               }
+       }
+}
\ No newline at end of file