[C] fallback nicely in case of IndexOutOfRangeEx (#4525)

This PR does 3 things:
- In case of Binding path with indexer, lookout for
  IndexOutOfRangeException in addition to KeyNotFoundException.
- in case of KeyNotFound or IndexOutOfRange, use the FallbackValue if
  any.
- in case of an uncaught exception, throw that exception instead of a
  TargetInvocationException.

- fixes #4516
This commit is contained in:
Stephane Delcroix 2018-11-24 11:08:15 +01:00 коммит произвёл GitHub
Родитель 94e6621f72
Коммит 9d9140eeb6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 53 добавлений и 8 удалений

Просмотреть файл

@ -610,15 +610,16 @@ namespace Xamarin.Forms
{
if (IsIndexer)
{
try
{
try {
value = LastGetter.Invoke(value, Arguments);
}
catch (TargetInvocationException ex)
{
if (!(ex.InnerException is KeyNotFoundException))
throw;
value = null;
catch (TargetInvocationException ex) {
if (ex.InnerException is KeyNotFoundException || ex.InnerException is IndexOutOfRangeException) {
value = null;
return false;
}
else
throw ex.InnerException;
}
return true;
}

Просмотреть файл

@ -197,7 +197,7 @@ namespace Xamarin.Forms.Internals
if (isTSource) {
try {
value = GetSourceValue(_getter((TSource)sourceObject), property.ReturnType);
} catch (Exception ex) when (ex is NullReferenceException || ex is KeyNotFoundException) {
} catch (Exception ex) when (ex is NullReferenceException || ex is KeyNotFoundException || ex is IndexOutOfRangeException) {
}
}
if (!BindingExpression.TryConvert(ref value, property, property.ReturnType, true)) {

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:Xamarin.Forms.Xaml.UnitTests"
x:Class="Xamarin.Forms.Xaml.UnitTests.Gh4516">
<Image x:Name="image" Source="{Binding Images[0], FallbackValue='foo.jpg'}" />
</ContentPage>

Просмотреть файл

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Xamarin.Forms;
using Xamarin.Forms.Core.UnitTests;
namespace Xamarin.Forms.Xaml.UnitTests
{
public class Gh4516VM {
public Uri[] Images { get; } = { };
}
public partial class Gh4516 : ContentPage
{
public Gh4516() => InitializeComponent();
public Gh4516(bool useCompiledXaml)
{
//this stub will be replaced at compile time
}
[TestFixture]
class Tests
{
[SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
[TearDown] public void TearDown() => Device.PlatformServices = null;
[TestCase(true), TestCase(false)]
public void BindingToEmptyCollection(bool useCompiledXaml)
{
Gh4516 layout = null;
Assert.DoesNotThrow(() => layout = new Gh4516(useCompiledXaml) { BindingContext = new Gh4516VM() });
Assert.That((layout.image.Source as FileImageSource).File, Is.EqualTo("foo.jpg"));
}
}
}
}