Browse Source

Fix BindingNotification handling in MultiBinding (#16102)

* Added failing test for #16070.

* Handle BindingNotifications in UntypedObservableBindingExpression.

Fixes #16070
Steven Kirk 1 year ago
parent
commit
f90afbb01a

+ 14 - 1
src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs

@@ -30,5 +30,18 @@ internal class UntypedObservableBindingExpression : UntypedBindingExpressionBase
 
     void IObserver<object?>.OnCompleted() { }
     void IObserver<object?>.OnError(Exception error) { }
-    void IObserver<object?>.OnNext(object? value) => PublishValue(value);
+    
+    void IObserver<object?>.OnNext(object? value)
+    {
+        if (value is BindingNotification n)
+        {
+            var v = n.Value;
+            var e = n.Error is not null ? new BindingError(n.Error, n.ErrorType) : null;
+            PublishValue(v, e);
+        }
+        else
+        {
+            PublishValue(value);
+        }
+    }
 }

+ 33 - 0
tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs

@@ -180,6 +180,28 @@ namespace Avalonia.Markup.UnitTests.Data
             Assert.Equal(target.ItemsView[2], source.C);
         }
 
+        [Fact]
+        public void Converter_Can_Return_BindingNotification()
+        {
+            var source = new { A = 1, B = 2, C = 3 };
+            var target = new TextBlock { DataContext = source };
+
+            var binding = new MultiBinding
+            {
+                Converter = new BindingNotificationConverter(),
+                Bindings = new[]
+                {
+                    new Binding { Path = "A" },
+                    new Binding { Path = "B" },
+                    new Binding { Path = "C" },
+                },
+            };
+
+            target.Bind(TextBlock.TextProperty, binding);
+
+            Assert.Equal("1,2,3-BindingNotification", target.Text);
+        }
+
         private class ConcatConverter : IMultiValueConverter
         {
             public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
@@ -203,5 +225,16 @@ namespace Avalonia.Markup.UnitTests.Data
                 return null;
             }
         }
+
+        private class BindingNotificationConverter : IMultiValueConverter
+        {
+            public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
+            {
+                return new BindingNotification(
+                    new ArgumentException(),
+                    BindingErrorType.Error,
+                    string.Join(",", values) + "-BindingNotification");
+            }
+        }
     }
 }