From f90afbb01aabceef65a9ae744d192e443b460710 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 25 Jun 2024 03:34:52 +0200 Subject: [PATCH] Fix BindingNotification handling in MultiBinding (#16102) * Added failing test for #16070. * Handle BindingNotifications in UntypedObservableBindingExpression. Fixes #16070 --- .../UntypedObservableBindingExpression.cs | 15 ++++++++- .../Data/MultiBindingTests.cs | 33 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs b/src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs index 1e26caa0512..df529d8675e 100644 --- a/src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs +++ b/src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs @@ -30,5 +30,18 @@ protected override void StopCore() void IObserver.OnCompleted() { } void IObserver.OnError(Exception error) { } - void IObserver.OnNext(object? value) => PublishValue(value); + + void IObserver.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); + } + } } diff --git a/tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs b/tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs index f6a4437a9ef..0a20c25b15f 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests.cs @@ -180,6 +180,28 @@ public void MultiBinding_Without_StringFormat_And_Converter() 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 values, Type targetType, object parameter, CultureInfo culture) @@ -203,5 +225,16 @@ public object Convert(IList values, Type targetType, object parameter, C return null; } } + + private class BindingNotificationConverter : IMultiValueConverter + { + public object Convert(IList values, Type targetType, object parameter, CultureInfo culture) + { + return new BindingNotification( + new ArgumentException(), + BindingErrorType.Error, + string.Join(",", values) + "-BindingNotification"); + } + } } }