瀏覽代碼

Merge pull request #2865 from jp2masa/multibinding-do-nothing

Fixed Binding.DoNothing for MultiBinding
danwalmsley 6 年之前
父節點
當前提交
b4bdbbded2

+ 6 - 6
src/Markup/Avalonia.Markup/Data/MultiBinding.cs

@@ -76,7 +76,12 @@ namespace Avalonia.Data
             }
             
             var children = Bindings.Select(x => x.Initiate(target, null));
-            var input = children.Select(x => x.Observable).CombineLatest().Select(x => ConvertValue(x, targetType, converter));
+
+            var input = children.Select(x => x.Observable)
+                                .CombineLatest()
+                                .Select(x => ConvertValue(x, targetType, converter))
+                                .Where(x => x != BindingOperations.DoNothing);
+
             var mode = Mode == BindingMode.Default ?
                 targetProperty?.GetMetadata(target.GetType()).DefaultBindingMode : Mode;
 
@@ -97,11 +102,6 @@ namespace Avalonia.Data
             var culture = CultureInfo.CurrentCulture;
             var converted = converter.Convert(values, targetType, ConverterParameter, culture);
 
-            if (converted == BindingOperations.DoNothing)
-            {
-                return converted;
-            }
-
             if (converted == AvaloniaProperty.UnsetValue)
             {
                 converted = FallbackValue;

+ 76 - 0
tests/Avalonia.Markup.Xaml.UnitTests/Converters/MultiValueConverterTests.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.Data.Converters;
+using Avalonia.UnitTests;
+using Xunit;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Converters
+{
+    public class MultiValueConverterTests : XamlTestBase
+    {
+        [Fact]
+        public void MultiValueConverter_Special_Values_Work()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                var xaml = @"
+<Window xmlns='https://github.com/avaloniaui'
+        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
+        xmlns:c='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Converters;assembly=Avalonia.Markup.Xaml.UnitTests'>
+    <TextBlock Name='textBlock'>
+        <TextBlock.Text>
+            <MultiBinding Converter='{x:Static c:TestMultiValueConverter.Instance}' FallbackValue='bar'>
+                <Binding Path='Item1' />
+                <Binding Path='Item2' />
+            </MultiBinding>
+        </TextBlock.Text>
+    </TextBlock>
+</Window>";
+                var loader = new AvaloniaXamlLoader();
+                var window = (Window)loader.Load(xaml);
+                var textBlock = window.FindControl<TextBlock>("textBlock");
+
+                window.ApplyTemplate();
+
+                window.DataContext = Tuple.Create(2, 2);
+                Assert.Equal("foo", textBlock.Text);
+
+                window.DataContext = Tuple.Create(-3, 3);
+                Assert.Equal("foo", textBlock.Text);
+
+                window.DataContext = Tuple.Create(0, 2);
+                Assert.Equal("bar", textBlock.Text);
+            }
+        }
+    }
+
+    public class TestMultiValueConverter : IMultiValueConverter
+    {
+        public static readonly TestMultiValueConverter Instance = new TestMultiValueConverter();
+
+        public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (values[0] is int i && values[1] is int j)
+            {
+                var p = i * j;
+
+                if (p > 0)
+                {
+                    return "foo";
+                }
+
+                if (p == 0)
+                {
+                    return AvaloniaProperty.UnsetValue;
+                }
+
+                return BindingOperations.DoNothing;
+            }
+
+            return "(default)";
+        }
+    }
+}