From 9ecd558af1863a3eacfac4ae4684b5fd089a6172 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 7 Feb 2016 14:15:50 +0100 Subject: [PATCH] Added FallbackValue to MultiBinding. Closes #411. --- .../Perspex.Markup.Xaml/Data/MultiBinding.cs | 20 +++++++++++-- .../Data/MultiBindingTests.cs | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Markup/Perspex.Markup.Xaml/Data/MultiBinding.cs b/src/Markup/Perspex.Markup.Xaml/Data/MultiBinding.cs index 2911335b8d..9cf218bbae 100644 --- a/src/Markup/Perspex.Markup.Xaml/Data/MultiBinding.cs +++ b/src/Markup/Perspex.Markup.Xaml/Data/MultiBinding.cs @@ -29,6 +29,11 @@ namespace Perspex.Markup.Xaml.Data /// public IMultiValueConverter Converter { get; set; } + /// + /// Gets or sets the value to use when the binding is unable to produce a value. + /// + public object FallbackValue { get; set; } + /// /// Gets or sets the binding mode. /// @@ -75,8 +80,7 @@ namespace Perspex.Markup.Xaml.Data var targetType = targetProperty?.PropertyType ?? typeof(object); var result = new BehaviorSubject(PerspexProperty.UnsetValue); var children = Bindings.Select(x => x.CreateSubject(target, null)); - var input = children.CombineLatest().Select(x => - Converter.Convert(x, targetType, null, CultureInfo.CurrentUICulture)); + var input = children.CombineLatest().Select(x => ConvertValue(x, targetType)); input.Subscribe(result); return result; } @@ -111,5 +115,17 @@ namespace Perspex.Markup.Xaml.Data break; } } + + private object ConvertValue(IList values, Type targetType) + { + var converted = Converter.Convert(values, targetType, null, CultureInfo.CurrentUICulture); + + if (converted == PerspexProperty.UnsetValue && FallbackValue != null) + { + converted = FallbackValue; + } + + return converted; + } } } \ No newline at end of file diff --git a/tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs index 908bb16e37..13c74aca30 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs @@ -39,6 +39,28 @@ namespace Perspex.Markup.Xaml.UnitTests.Data Assert.Equal("1,2,3", result); } + [Fact] + public void Should_Return_FallbackValue_When_Converter_Returns_UnsetValue() + { + var target = new TextBlock(); + var source = new { A = 1, B = 2, C = 3 }; + var binding = new MultiBinding + { + Converter = new UnsetValueConverter(), + Bindings = new[] + { + new Binding { Path = "A" }, + new Binding { Path = "B" }, + new Binding { Path = "C" }, + }, + FallbackValue = "fallback", + }; + + target.Bind(TextBlock.TextProperty, binding); + + Assert.Equal("fallback", target.Text); + } + private class ConcatConverter : IMultiValueConverter { public object Convert(IList values, Type targetType, object parameter, CultureInfo culture) @@ -46,5 +68,13 @@ namespace Perspex.Markup.Xaml.UnitTests.Data return string.Join(",", values); } } + + private class UnsetValueConverter : IMultiValueConverter + { + public object Convert(IList values, Type targetType, object parameter, CultureInfo culture) + { + return PerspexProperty.UnsetValue; + } + } } }