Browse Source

Merge branch 'master' into fixes/1221-getvisualsat-returns-non-children

danwalmsley 8 years ago
parent
commit
cb6775eebc

+ 8 - 8
build/XUnit.props

@@ -1,14 +1,14 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
+    <PackageReference Include="xunit" Version="2.3.0" />
     <PackageReference Include="xunit.abstractions" Version="2.0.1" />
-    <PackageReference Include="xunit.assert" Version="2.3.0-beta5-build3769" />
-    <PackageReference Include="xunit.core" Version="2.3.0-beta5-build3769" />
-    <PackageReference Include="xunit.extensibility.core" Version="2.3.0-beta5-build3769" />
-    <PackageReference Include="xunit.extensibility.execution" Version="2.3.0-beta5-build3769" />
-    <PackageReference Include="xunit.runner.console" Version="2.3.0-beta5-build3769" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
-    <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta5-build3769" />
+    <PackageReference Include="xunit.assert" Version="2.3.0" />
+    <PackageReference Include="xunit.core" Version="2.3.0" />
+    <PackageReference Include="xunit.extensibility.core" Version="2.3.0" />
+    <PackageReference Include="xunit.extensibility.execution" Version="2.3.0" />
+    <PackageReference Include="xunit.runner.console" Version="2.3.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
+    <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />

+ 18 - 1
src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs

@@ -154,7 +154,24 @@ namespace Avalonia.Markup.Data
         /// </returns>
         public bool SetValue(object value, BindingPriority priority = BindingPriority.LocalValue)
         {
-            return (Leaf as ISettableNode)?.SetTargetValue(value, priority) ?? false;
+            if (Leaf is ISettableNode settable)
+            {
+                var node = _node;
+                while (node != null)
+                {
+                    if (node is ITransformNode transform)
+                    {
+                        value = transform.Transform(value);
+                        if (value is BindingNotification)
+                        {
+                            return false;
+                        }
+                    }
+                    node = node.Next;
+                }
+                return settable.SetTargetValue(value, priority);
+            }
+            return false;
         }
 
         /// <summary>

+ 11 - 0
src/Markup/Avalonia.Markup/Data/ITransformNode.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Avalonia.Markup.Data
+{
+    interface ITransformNode
+    {
+        object Transform(object value);
+    }
+}

+ 12 - 1
src/Markup/Avalonia.Markup/Data/LogicalNotNode.cs

@@ -7,7 +7,7 @@ using Avalonia.Data;
 
 namespace Avalonia.Markup.Data
 {
-    internal class LogicalNotNode : ExpressionNode
+    internal class LogicalNotNode : ExpressionNode, ITransformNode
     {
         public override string Description => "!";
 
@@ -61,5 +61,16 @@ namespace Avalonia.Markup.Data
 
             return AvaloniaProperty.UnsetValue;
         }
+
+        public object Transform(object value)
+        {
+            var originalType = value.GetType();
+            var negated = Negate(value);
+            if (negated is BindingNotification)
+            {
+                return negated;
+            }
+            return Convert.ChangeType(negated, originalType);
+        }
     }
 }

+ 19 - 1
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs

@@ -105,14 +105,32 @@ namespace Avalonia.Markup.UnitTests.Data
         }
 
         [Fact]
-        public void SetValue_Should_Return_False()
+        public void SetValue_Should_Return_False_For_Invalid_Value()
         {
             var data = new { Foo = "foo" };
             var target = new ExpressionObserver(data, "!Foo");
+            target.Subscribe(_ => { });
 
             Assert.False(target.SetValue("bar"));
 
             GC.KeepAlive(data);
         }
+
+        [Fact]
+        public void Can_SetValue_For_Valid_Value()
+        {
+            var data = new Test { Foo = true };
+            var target = new ExpressionObserver(data, "!Foo");
+            target.Subscribe(_ => { });
+
+            Assert.True(target.SetValue(true));
+
+            Assert.False(data.Foo);
+        }
+
+        private class Test
+        {
+            public bool Foo { get; set; }
+        }
     }
 }