summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorE.Z. Hart <hartez@users.noreply.github.com>2016-07-18 17:16:47 -0600
committerJason Smith <jason.smith@xamarin.com>2016-07-18 16:16:47 -0700
commit272033723ea275ceb8a288fa605eafd035c79f2d (patch)
treeabc639d0f5627f3877f9e237e473bda168e9e030
parentc9da550ce4987e01c1bbce9d0a17b860e1d300b3 (diff)
downloadxamarin-forms-272033723ea275ceb8a288fa605eafd035c79f2d.tar.gz
xamarin-forms-272033723ea275ceb8a288fa605eafd035c79f2d.tar.bz2
xamarin-forms-272033723ea275ceb8a288fa605eafd035c79f2d.zip
Windows image loader error handling (#260)
* Repros for various image issues * Log image loading errors * Better repro instructions and user interface * Image loading tests now running on WinRT/UWP phone/tablet/desktop * Move FailImageSource into shared project * Move FailImageSource into shared project * Update docs
-rw-r--r--Xamarin.Forms.ControlGallery.Windows/BrokenImageSourceHandler.cs24
-rw-r--r--Xamarin.Forms.ControlGallery.Windows/Properties/AssemblyInfo.cs8
-rw-r--r--Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj1
-rw-r--r--Xamarin.Forms.ControlGallery.WindowsPhone/Properties/AssemblyInfo.cs8
-rw-r--r--Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj3
-rw-r--r--Xamarin.Forms.ControlGallery.WindowsUniversal/Properties/AssemblyInfo.cs9
-rw-r--r--Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj4
-rw-r--r--Xamarin.Forms.ControlGallery.WindowsUniversal/invalidimage.jpg1
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FailImageSource.cs12
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/ImageLoadingErrorHandling.cs100
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems2
-rw-r--r--Xamarin.Forms.Core/ImageSource.cs2
-rw-r--r--Xamarin.Forms.Core/UriImageSource.cs16
-rw-r--r--Xamarin.Forms.Platform.UAP/Properties/AssemblyInfo.cs4
-rw-r--r--Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj6
-rw-r--r--Xamarin.Forms.Platform.WinRT/FileImageSourceHandler.cs4
-rw-r--r--Xamarin.Forms.Platform.WinRT/IImageSourceHandler.cs2
-rw-r--r--Xamarin.Forms.Platform.WinRT/ImageRenderer.cs35
-rw-r--r--Xamarin.Forms.Platform.WinRT/Properties/AssemblyInfo.cs4
-rw-r--r--Xamarin.Forms.Platform.WinRT/StreamImagesourceHandler.cs2
-rw-r--r--Xamarin.Forms.Platform.WinRT/UriImageSourceHandler.cs (renamed from Xamarin.Forms.Platform.WinRT/ImageLoaderSourceHandler.cs)11
-rw-r--r--Xamarin.Forms.Platform.WinRT/WindowsBasePlatformServices.cs9
-rw-r--r--Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj2
-rw-r--r--docs/Xamarin.Forms.Core/Xamarin.Forms/ImageSource.xml13
24 files changed, 244 insertions, 38 deletions
diff --git a/Xamarin.Forms.ControlGallery.Windows/BrokenImageSourceHandler.cs b/Xamarin.Forms.ControlGallery.Windows/BrokenImageSourceHandler.cs
new file mode 100644
index 00000000..ffe999ee
--- /dev/null
+++ b/Xamarin.Forms.ControlGallery.Windows/BrokenImageSourceHandler.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+using WImageSource = Windows.UI.Xaml.Media.ImageSource;
+
+#if WINDOWS_UWP
+using Xamarin.Forms.Platform.UWP;
+
+namespace Xamarin.Forms.ControlGallery.WindowsUniversal
+#else
+using Xamarin.Forms.Platform.WinRT;
+
+namespace Xamarin.Forms.ControlGallery.WinRT
+#endif
+{
+ public sealed class BrokenImageSourceHandler : IImageSourceHandler
+ {
+ public Task<WImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
+ {
+ throw new Exception("Fail");
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.ControlGallery.Windows/Properties/AssemblyInfo.cs b/Xamarin.Forms.ControlGallery.Windows/Properties/AssemblyInfo.cs
index 89577935..cf2e0174 100644
--- a/Xamarin.Forms.ControlGallery.Windows/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.ControlGallery.Windows/Properties/AssemblyInfo.cs
@@ -1,6 +1,9 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Xamarin.Forms.ControlGallery.WinRT;
+using Xamarin.Forms.Controls;
+using Xamarin.Forms.Platform.WinRT;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -26,4 +29,7 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: ComVisible(false)] \ No newline at end of file
+[assembly: ComVisible(false)]
+
+// Deliberately broken image source and handler so we can test handling of image loading errors
+[assembly: ExportImageSourceHandler(typeof(FailImageSource), typeof(BrokenImageSourceHandler))] \ No newline at end of file
diff --git a/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj b/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj
index 6d03d703..c93c45b9 100644
--- a/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj
+++ b/Xamarin.Forms.ControlGallery.Windows/Xamarin.Forms.ControlGallery.Windows.csproj
@@ -139,6 +139,7 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
+ <Compile Include="BrokenImageSourceHandler.cs" />
<Compile Include="BrokenNativeControl.cs" />
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/Properties/AssemblyInfo.cs b/Xamarin.Forms.ControlGallery.WindowsPhone/Properties/AssemblyInfo.cs
index 7be28e92..3236c831 100644
--- a/Xamarin.Forms.ControlGallery.WindowsPhone/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.ControlGallery.WindowsPhone/Properties/AssemblyInfo.cs
@@ -1,6 +1,9 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Xamarin.Forms.ControlGallery.WinRT;
+using Xamarin.Forms.Controls;
+using Xamarin.Forms.Platform.WinRT;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -26,4 +29,7 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: ComVisible(false)] \ No newline at end of file
+[assembly: ComVisible(false)]
+
+// Deliberately broken image source and handler so we can test handling of image loading errors
+[assembly: ExportImageSourceHandler(typeof(FailImageSource), typeof(BrokenImageSourceHandler))] \ No newline at end of file
diff --git a/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj b/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj
index 9481ccce..16a042b0 100644
--- a/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj
+++ b/Xamarin.Forms.ControlGallery.WindowsPhone/Xamarin.Forms.ControlGallery.WindowsPhone.csproj
@@ -110,6 +110,9 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="..\Xamarin.Forms.ControlGallery.Windows\BrokenImageSourceHandler.cs">
+ <Link>BrokenImageSourceHandler.cs</Link>
+ </Compile>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/Properties/AssemblyInfo.cs b/Xamarin.Forms.ControlGallery.WindowsUniversal/Properties/AssemblyInfo.cs
index 405b6c6f..b83ca10b 100644
--- a/Xamarin.Forms.ControlGallery.WindowsUniversal/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/Properties/AssemblyInfo.cs
@@ -1,6 +1,10 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using Xamarin.Forms;
+using Xamarin.Forms.ControlGallery.WindowsUniversal;
+using Xamarin.Forms.Controls;
+using Xamarin.Forms.Platform.UWP;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -26,4 +30,7 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: ComVisible(false)] \ No newline at end of file
+[assembly: ComVisible(false)]
+
+// Deliberately broken image source and handler so we can test handling of image loading errors
+[assembly: ExportImageSourceHandler(typeof(FailImageSource), typeof(BrokenImageSourceHandler))] \ No newline at end of file
diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj b/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj
index e2cb27df..d5339b71 100644
--- a/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj
+++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/Xamarin.Forms.ControlGallery.WindowsUniversal.csproj
@@ -117,6 +117,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="coffee.png" />
+ <Content Include="invalidimage.jpg" />
<Content Include="toolbar_close.png" />
<None Include="project.json" />
<Content Include="..\Xamarin.Forms.ControlGallery.WP8\bank.png">
@@ -150,6 +151,9 @@
<Link>seth.png</Link>
</Content>
<Content Include="Properties\default.rd.xml" />
+ <Compile Include="..\Xamarin.Forms.ControlGallery.Windows\BrokenImageSourceHandler.cs">
+ <Link>BrokenImageSourceHandler.cs</Link>
+ </Compile>
<Compile Include="..\Xamarin.Forms.ControlGallery.Windows\StringProvider.cs">
<Link>StringProvider.cs</Link>
</Compile>
diff --git a/Xamarin.Forms.ControlGallery.WindowsUniversal/invalidimage.jpg b/Xamarin.Forms.ControlGallery.WindowsUniversal/invalidimage.jpg
new file mode 100644
index 00000000..6c7ebbb3
--- /dev/null
+++ b/Xamarin.Forms.ControlGallery.WindowsUniversal/invalidimage.jpg
@@ -0,0 +1 @@
+This is certainly not a real JPEG. \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FailImageSource.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FailImageSource.cs
new file mode 100644
index 00000000..a3dfbb3b
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FailImageSource.cs
@@ -0,0 +1,12 @@
+using System.Threading.Tasks;
+
+namespace Xamarin.Forms.Controls
+{
+ public sealed class FailImageSource : ImageSource
+ {
+ public override Task<bool> Cancel()
+ {
+ return Task.FromResult(false);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/ImageLoadingErrorHandling.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/ImageLoadingErrorHandling.cs
new file mode 100644
index 00000000..fe1f6356
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/ImageLoadingErrorHandling.cs
@@ -0,0 +1,100 @@
+using System;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+namespace Xamarin.Forms.Controls
+{
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.None, 0, "Image Loading Error Handling", PlatformAffected.WinRT)]
+ public class ImageLoadingErrorHandling : TestContentPage
+ {
+ protected override void Init()
+ {
+ Log.Listeners.Add(
+ new DelegateLogListener((c, m) => Device.BeginInvokeOnMainThread(() => DisplayAlert(c, m, "Cool, Thanks"))));
+
+ var image = new Image() {BackgroundColor = Color.White};
+
+ Grid legit = CreateTest(() => image.Source = ImageSource.FromFile("coffee.png"),
+ "Valid Image",
+ "Clicking this button should load an image at the top of the page.",
+ Color.Silver);
+
+ Grid invalidImageFileName = CreateTest(() => image.Source = ImageSource.FromFile("fake.png"),
+ "Non-existent Image File",
+ "Clicking this button should display an alert dialog with an error that the image failed to load.");
+
+ Grid invalidImageFile = CreateTest(() => image.Source = ImageSource.FromFile("invalidimage.jpg"),
+ "Invalid Image File (bad data)",
+ "Clicking this button should display an alert dialog with an error that the image failed to load.",
+ Color.Silver);
+
+ Grid fakeUri = CreateTest(() => image.Source = ImageSource.FromUri(new Uri("http://not.real")),
+ "Non-existent URI",
+ Device.OS == TargetPlatform.Windows && Device.Idiom == TargetIdiom.Phone
+ ? "Clicking this button should display an alert dialog. The error message should include the text 'NotFound'."
+ : "Clicking this button should display an alert dialog. The error message should include the text 'the server name or address could not be resolved'.");
+
+ // This used to crash the app with an uncatchable error; need to make sure it's not still doing that
+ Grid crashImage = CreateTest(() => image.Source = new FailImageSource(),
+ "Source Throws Exception",
+ "Clicking this button should display an alert dialog. The error messages hould include the test 'error updating image source'.",
+ Color.Silver);
+
+ Grid uriInvalidImageData =
+ CreateTest(() => image.Source = ImageSource.FromUri(new Uri("https://gist.githubusercontent.com/hartez/a2dda6b5c78852bcf4832af18f21a023/raw/39f4cd2e9fe8514694ac7fa0943017eb9308853d/corrupt.jpg")),
+ "Valid URI with invalid image file",
+ "Clicking this button should display an alert dialog. The error message should include the text 'UriImageSourceHandler could not load https://gist.githubusercontent.com/hartez/a2dda6b5c78852bcf4832af18f21a023/raw/39f4cd2e9fe8514694ac7fa0943017eb9308853d/corrupt.jpg'");
+
+ Content = new StackLayout
+ {
+ Children =
+ {
+ image,
+ legit,
+ invalidImageFileName,
+ invalidImageFile,
+ fakeUri,
+ crashImage,
+ uriInvalidImageData
+ }
+ };
+ }
+
+ static Grid CreateTest(Action imageLoadAction, string title, string instructions, Color? backgroundColor = null)
+ {
+ var button = new Button { Text = "Test" };
+
+ button.Clicked += (sender, args) => imageLoadAction();
+
+ var titleLabel = new Label
+ {
+ Text = title,
+ FontAttributes = FontAttributes.Bold
+ };
+
+ var label = new Label
+ {
+ Text = instructions
+ };
+
+ var grid = new Grid
+ {
+ ColumnDefinitions =
+ new ColumnDefinitionCollection { new ColumnDefinition(), new ColumnDefinition(), new ColumnDefinition() },
+ RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = 80 } }
+ };
+
+ if (backgroundColor.HasValue)
+ {
+ grid.BackgroundColor = backgroundColor.Value;
+ }
+
+ grid.AddChild(titleLabel, 0, 0);
+ grid.AddChild(label, 1, 0);
+ grid.AddChild(button, 2, 0);
+
+ return grid;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
index cd836f39..30ad7ee4 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
@@ -118,6 +118,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38416.xaml.cs">
<DependentUpon>Bugzilla38416.xaml</DependentUpon>
</Compile>
+ <Compile Include="$(MSBuildThisFileDirectory)FailImageSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)InputTransparentIssue.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IsInvokeRequiredRaceCondition.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IsPasswordToggleTest.cs" />
@@ -159,6 +160,7 @@
<Compile Include="$(MSBuildThisFileDirectory)TestPages\ScreenshotConditionalApp.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla41842.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla42277.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)ImageLoadingErrorHandling.cs" />
<Compile Include="$(MSBuildThisFileDirectory)_Template.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1028.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1075.cs" />
diff --git a/Xamarin.Forms.Core/ImageSource.cs b/Xamarin.Forms.Core/ImageSource.cs
index 03c98f2d..f65d0610 100644
--- a/Xamarin.Forms.Core/ImageSource.cs
+++ b/Xamarin.Forms.Core/ImageSource.cs
@@ -14,7 +14,7 @@ namespace Xamarin.Forms
TaskCompletionSource<bool> _completionSource;
- internal ImageSource()
+ protected ImageSource()
{
}
diff --git a/Xamarin.Forms.Core/UriImageSource.cs b/Xamarin.Forms.Core/UriImageSource.cs
index a313f274..80551160 100644
--- a/Xamarin.Forms.Core/UriImageSource.cs
+++ b/Xamarin.Forms.Core/UriImageSource.cs
@@ -68,7 +68,8 @@ namespace Xamarin.Forms
{
OnLoadingStarted();
userToken.Register(CancellationTokenSource.Cancel);
- Stream stream = null;
+ Stream stream;
+
try
{
stream = await GetStreamAsync(Uri, CancellationTokenSource.Token);
@@ -78,14 +79,13 @@ namespace Xamarin.Forms
{
OnLoadingCompleted(true);
throw;
-#if DEBUG
}
- catch (Exception e)
+ catch (Exception ex)
{
- Debug.WriteLine(e);
+ Log.Warning("Image Loading", $"Error getting stream for {Uri}: {ex}");
throw;
-#endif
}
+
return stream;
}
@@ -121,8 +121,9 @@ namespace Xamarin.Forms
{
stream = await Device.GetStreamAsync(uri, cancellationToken).ConfigureAwait(false);
}
- catch (Exception)
+ catch (Exception ex)
{
+ Log.Warning("Image Loading", $"Error getting stream for {Uri}: {ex}");
stream = null;
}
}
@@ -166,8 +167,9 @@ namespace Xamarin.Forms
if (stream == null)
return null;
}
- catch (Exception)
+ catch (Exception ex)
{
+ Log.Warning("Image Loading", $"Error getting stream for {Uri}: {ex}");
return null;
}
diff --git a/Xamarin.Forms.Platform.UAP/Properties/AssemblyInfo.cs b/Xamarin.Forms.Platform.UAP/Properties/AssemblyInfo.cs
index 83c6dfb7..bf1936ae 100644
--- a/Xamarin.Forms.Platform.UAP/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.Platform.UAP/Properties/AssemblyInfo.cs
@@ -37,8 +37,8 @@ using Xamarin.Forms.Platform.UWP;
//ImageSources
[assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
-[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImagesourceHandler))]
-[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(ImageLoaderSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(UriImageSourceHandler))]
// Pages
diff --git a/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj b/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj
index c992f826..5ce6221e 100644
--- a/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj
+++ b/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj
@@ -164,6 +164,9 @@
<Compile Include="..\Xamarin.Forms.Platform.WinRT\PlatformEffect.cs">
<Link>PlatformEffect.cs</Link>
</Compile>
+ <Compile Include="..\Xamarin.Forms.Platform.WinRT\UriImageSourceHandler.cs">
+ <Link>UriImageSourceHandler.cs</Link>
+ </Compile>
<Compile Include="..\Xamarin.Forms.Platform.WinRT\ViewExtensions.cs">
<Link>ViewExtensions.cs</Link>
</Compile>
@@ -283,9 +286,6 @@
<Compile Include="..\Xamarin.Forms.Platform.WinRT\ImageConverter.cs">
<Link>ImageConverter.cs</Link>
</Compile>
- <Compile Include="..\Xamarin.Forms.Platform.WinRT\ImageLoaderSourceHandler.cs">
- <Link>ImageLoaderSourceHandler.cs</Link>
- </Compile>
<Compile Include="..\Xamarin.Forms.Platform.WinRT\ImageRenderer.cs">
<Link>ImageRenderer.cs</Link>
</Compile>
diff --git a/Xamarin.Forms.Platform.WinRT/FileImageSourceHandler.cs b/Xamarin.Forms.Platform.WinRT/FileImageSourceHandler.cs
index c9c6f16b..2e1a907a 100644
--- a/Xamarin.Forms.Platform.WinRT/FileImageSourceHandler.cs
+++ b/Xamarin.Forms.Platform.WinRT/FileImageSourceHandler.cs
@@ -13,10 +13,10 @@ namespace Xamarin.Forms.Platform.WinRT
{
public sealed class FileImageSourceHandler : IImageSourceHandler
{
- public Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesoure, CancellationToken cancellationToken = new CancellationToken())
+ public Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
{
Windows.UI.Xaml.Media.ImageSource image = null;
- var filesource = imagesoure as FileImageSource;
+ var filesource = imagesource as FileImageSource;
if (filesource != null)
{
string file = filesource.File;
diff --git a/Xamarin.Forms.Platform.WinRT/IImageSourceHandler.cs b/Xamarin.Forms.Platform.WinRT/IImageSourceHandler.cs
index 91eff534..457d48e4 100644
--- a/Xamarin.Forms.Platform.WinRT/IImageSourceHandler.cs
+++ b/Xamarin.Forms.Platform.WinRT/IImageSourceHandler.cs
@@ -11,6 +11,6 @@ namespace Xamarin.Forms.Platform.WinRT
{
public interface IImageSourceHandler : IRegisterable
{
- Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesoure, CancellationToken cancellationToken = default(CancellationToken));
+ Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = default(CancellationToken));
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
index 370da329..fa676c18 100644
--- a/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
@@ -34,12 +35,13 @@ namespace Xamarin.Forms.Platform.WinRT
if (Control != null)
{
Control.ImageOpened -= OnImageOpened;
+ Control.ImageFailed -= OnImageFailed;
}
base.Dispose(disposing);
}
- protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
+ protected override async void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
@@ -49,20 +51,21 @@ namespace Xamarin.Forms.Platform.WinRT
{
var image = new Windows.UI.Xaml.Controls.Image();
image.ImageOpened += OnImageOpened;
+ image.ImageFailed += OnImageFailed;
SetNativeControl(image);
}
- UpdateSource();
+ await UpdateSource();
UpdateAspect();
}
}
- protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ protected override async void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Image.SourceProperty.PropertyName)
- UpdateSource();
+ await UpdateSource();
else if (e.PropertyName == Image.AspectProperty.PropertyName)
UpdateAspect();
}
@@ -87,6 +90,14 @@ namespace Xamarin.Forms.Platform.WinRT
{
RefreshImage();
}
+
+ ((IImageController)Element)?.SetIsLoading(false);
+ }
+
+ void OnImageFailed(object sender, ExceptionRoutedEventArgs exceptionRoutedEventArgs)
+ {
+ Log.Warning("Image Loading", $"Image failed to load: {exceptionRoutedEventArgs.ErrorMessage}" );
+ ((IImageController)Element)?.SetIsLoading(false);
}
void RefreshImage()
@@ -109,7 +120,7 @@ namespace Xamarin.Forms.Platform.WinRT
}
}
- async void UpdateSource()
+ async Task UpdateSource()
{
((IImageController)Element).SetIsLoading(true);
@@ -117,7 +128,8 @@ namespace Xamarin.Forms.Platform.WinRT
IImageSourceHandler handler;
if (source != null && (handler = Registrar.Registered.GetHandler<IImageSourceHandler>(source.GetType())) != null)
{
- Windows.UI.Xaml.Media.ImageSource imagesource;
+ Windows.UI.Xaml.Media.ImageSource imagesource = null;
+
try
{
imagesource = await handler.LoadImageAsync(source);
@@ -126,18 +138,25 @@ namespace Xamarin.Forms.Platform.WinRT
{
imagesource = null;
}
+ catch (Exception ex)
+ {
+ Log.Warning("Image Loading", $"Error updating image source: {ex}");
+ }
// In the time it takes to await the imagesource, some zippy little app
// might have disposed of this Image already.
if (Control != null)
+ {
Control.Source = imagesource;
+ }
RefreshImage();
}
else
+ {
Control.Source = null;
-
- ((IImageController)Element)?.SetIsLoading(false);
+ ((IImageController)Element)?.SetIsLoading(false);
+ }
}
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.WinRT/Properties/AssemblyInfo.cs b/Xamarin.Forms.Platform.WinRT/Properties/AssemblyInfo.cs
index d1975076..83023289 100644
--- a/Xamarin.Forms.Platform.WinRT/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.Platform.WinRT/Properties/AssemblyInfo.cs
@@ -37,8 +37,8 @@ using Xamarin.Forms.Platform.WinRT;
//ImageSources
[assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
-[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImagesourceHandler))]
-[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(ImageLoaderSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(UriImageSourceHandler))]
// Pages
diff --git a/Xamarin.Forms.Platform.WinRT/StreamImagesourceHandler.cs b/Xamarin.Forms.Platform.WinRT/StreamImagesourceHandler.cs
index 20d2c504..da2b1ff0 100644
--- a/Xamarin.Forms.Platform.WinRT/StreamImagesourceHandler.cs
+++ b/Xamarin.Forms.Platform.WinRT/StreamImagesourceHandler.cs
@@ -12,7 +12,7 @@ namespace Xamarin.Forms.Platform.UWP
namespace Xamarin.Forms.Platform.WinRT
#endif
{
- public sealed class StreamImagesourceHandler : IImageSourceHandler
+ public sealed class StreamImageSourceHandler : IImageSourceHandler
{
public async Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
{
diff --git a/Xamarin.Forms.Platform.WinRT/ImageLoaderSourceHandler.cs b/Xamarin.Forms.Platform.WinRT/UriImageSourceHandler.cs
index d2b223b5..1263c355 100644
--- a/Xamarin.Forms.Platform.WinRT/ImageLoaderSourceHandler.cs
+++ b/Xamarin.Forms.Platform.WinRT/UriImageSourceHandler.cs
@@ -14,11 +14,11 @@ namespace Xamarin.Forms.Platform.UWP
namespace Xamarin.Forms.Platform.WinRT
#endif
{
- public sealed class ImageLoaderSourceHandler : IImageSourceHandler
+ public sealed class UriImageSourceHandler : IImageSourceHandler
{
- public async Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesoure, CancellationToken cancellationToken = new CancellationToken())
+ public async Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
{
- var imageLoader = imagesoure as UriImageSource;
+ var imageLoader = imagesource as UriImageSource;
if (imageLoader?.Uri == null)
return null;
@@ -36,11 +36,10 @@ namespace Xamarin.Forms.Platform.WinRT
await image.SetSourceAsync(stream);
return image;
}
- catch (Exception ex)
+ catch (Exception ex)
{
- Debug.WriteLine(ex);
+ Log.Warning("Image Loading", $"{nameof(UriImageSourceHandler)} could not load {imageLoader.Uri}: {ex}");
- // Because this literally throws System.Exception
// According to https://msdn.microsoft.com/library/windows/apps/jj191522
// this can happen if the image data is bad or the app is close to its
// memory limit
diff --git a/Xamarin.Forms.Platform.WinRT/WindowsBasePlatformServices.cs b/Xamarin.Forms.Platform.WinRT/WindowsBasePlatformServices.cs
index 603ec401..49589a8a 100644
--- a/Xamarin.Forms.Platform.WinRT/WindowsBasePlatformServices.cs
+++ b/Xamarin.Forms.Platform.WinRT/WindowsBasePlatformServices.cs
@@ -99,7 +99,14 @@ namespace Xamarin.Forms.Platform.WinRT
using (var client = new HttpClient())
{
HttpResponseMessage streamResponse = await client.GetAsync(uri.AbsoluteUri).ConfigureAwait(false);
- return streamResponse.IsSuccessStatusCode ? await streamResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) : null;
+
+ if (!streamResponse.IsSuccessStatusCode)
+ {
+ Log.Warning("HTTP Request", $"Could not retrieve {uri}, status code {streamResponse.StatusCode}");
+ return null;
+ }
+
+ return await streamResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
}
diff --git a/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj b/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj
index 6d28b900..f6b3566a 100644
--- a/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj
+++ b/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj
@@ -125,7 +125,7 @@
<Compile Include="HeightConverter.cs" />
<Compile Include="ICellRenderer.cs" />
<Compile Include="IImageSourceHandler.cs" />
- <Compile Include="ImageLoaderSourceHandler.cs" />
+ <Compile Include="UriImageSourceHandler.cs" />
<Compile Include="ImageRenderer.cs" />
<Compile Include="IVisualElementRenderer.cs" />
<Compile Include="LabelRenderer.cs" />
diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms/ImageSource.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms/ImageSource.xml
index 162b3a10..b6d44562 100644
--- a/docs/Xamarin.Forms.Core/Xamarin.Forms/ImageSource.xml
+++ b/docs/Xamarin.Forms.Core/Xamarin.Forms/ImageSource.xml
@@ -26,6 +26,19 @@
<remarks>To be added.</remarks>
</Docs>
<Members>
+ <Member MemberName=".ctor">
+ <MemberSignature Language="C#" Value="protected ImageSource ();" />
+ <MemberSignature Language="ILAsm" Value=".method familyhidebysig specialname rtspecialname instance void .ctor() cil managed" />
+ <MemberType>Constructor</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <Parameters />
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
<Member MemberName="Cancel">
<MemberSignature Language="C#" Value="public virtual System.Threading.Tasks.Task&lt;bool&gt; Cancel ();" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig newslot virtual instance class System.Threading.Tasks.Task`1&lt;bool&gt; Cancel() cil managed" />