Browse Source

Added RelativeSource=Self binding mode.

Steven Kirk 9 years ago
parent
commit
8f21388e28

+ 4 - 0
src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs

@@ -115,6 +115,10 @@ namespace Avalonia.Markup.Xaml.Data
                     anchor,
                     enableDataValidation);
             }
+            else if (RelativeSource.Mode == RelativeSourceMode.Self)
+            {
+                observer = CreateSourceObserver(target, pathInfo.Path, enableDataValidation);
+            }
             else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
             {
                 observer = CreateTemplatedParentObserver(target, pathInfo.Path);

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/Data/RelativeSource.cs

@@ -5,6 +5,7 @@ namespace Avalonia.Markup.Xaml.Data
 {
     public enum RelativeSourceMode
     {
+        Self,
         DataContext,
         TemplatedParent,
     }

+ 63 - 0
tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Self.cs

@@ -0,0 +1,63 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Moq;
+using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.Markup.Xaml.Data;
+using Avalonia.Styling;
+using Xunit;
+using System.Reactive.Disposables;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Data
+{
+    public class BindingTests_Self
+    {
+        [Fact]
+        public void Binding_To_Property_On_Self_Should_Work()
+        {
+            var target = new TextBlock
+            {
+                Tag = "Hello World!",
+                [!TextBlock.TextProperty] = new Binding("Tag")
+                {
+                    RelativeSource = new RelativeSource(RelativeSourceMode.Self)
+                },
+            };
+
+            Assert.Equal("Hello World!", target.Text);
+        }
+
+        [Fact]
+        public void TwoWay_Binding_To_Property_On_Self_Should_Work()
+        {
+            var target = new TextBlock
+            {
+                Tag = "Hello World!",
+                [!TextBlock.TextProperty] = new Binding("Tag", BindingMode.TwoWay)
+                {
+                    RelativeSource = new RelativeSource(RelativeSourceMode.Self)
+                },
+            };
+
+            Assert.Equal("Hello World!", target.Text);
+            target.Text = "Goodbye cruel world :(";
+            Assert.Equal("Goodbye cruel world :(", target.Text);
+        }
+
+        private Mock<IControl> CreateTarget(
+            ITemplatedControl templatedParent = null,
+            string text = null)
+        {
+            var result = new Mock<IControl>();
+
+            result.Setup(x => x.GetValue(Control.TemplatedParentProperty)).Returns(templatedParent);
+            result.Setup(x => x.GetValue((AvaloniaProperty)Control.TemplatedParentProperty)).Returns(templatedParent);
+            result.Setup(x => x.GetValue((AvaloniaProperty)TextBox.TextProperty)).Returns(text);
+            result.Setup(x => x.Bind(It.IsAny<AvaloniaProperty>(), It.IsAny<IObservable<object>>(), It.IsAny<BindingPriority>()))
+                .Returns(Disposable.Empty);
+            return result;
+        }
+    }
+}