diff options
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<bool> Cancel ();" /> <MemberSignature Language="ILAsm" Value=".method public hidebysig newslot virtual instance class System.Threading.Tasks.Task`1<bool> Cancel() cil managed" /> |