using System; using System.ComponentModel; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; #if WINDOWS_UWP namespace Xamarin.Forms.Platform.UWP #else namespace Xamarin.Forms.Platform.WinRT #endif { public class ImageRenderer : ViewRenderer { bool _measured; public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) { if (Control.Source == null) return new SizeRequest(); _measured = true; var result = new Size { Width = ((BitmapImage)Control.Source).PixelWidth, Height = ((BitmapImage)Control.Source).PixelHeight }; return new SizeRequest(result); } protected override void Dispose(bool disposing) { if (Control != null) { Control.ImageOpened -= OnImageOpened; } base.Dispose(disposing); } protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); if (e.NewElement != null) { if (Control == null) { var image = new Windows.UI.Xaml.Controls.Image(); image.ImageOpened += OnImageOpened; SetNativeControl(image); } UpdateSource(); UpdateAspect(); } } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == Image.SourceProperty.PropertyName) UpdateSource(); else if (e.PropertyName == Image.AspectProperty.PropertyName) UpdateAspect(); } static Stretch GetStretch(Aspect aspect) { switch (aspect) { case Aspect.Fill: return Stretch.Fill; case Aspect.AspectFill: return Stretch.UniformToFill; default: case Aspect.AspectFit: return Stretch.Uniform; } } void OnImageOpened(object sender, RoutedEventArgs routedEventArgs) { if (_measured) { RefreshImage(); } } void RefreshImage() { Element?.InvalidateMeasure(InvalidationTrigger.RendererReady); } void UpdateAspect() { Control.Stretch = GetStretch(Element.Aspect); } async void UpdateSource() { Element.SetValueCore(Image.IsLoadingPropertyKey, true); ImageSource source = Element.Source; IImageSourceHandler handler; if (source != null && (handler = Registrar.Registered.GetHandler(source.GetType())) != null) { Windows.UI.Xaml.Media.ImageSource imagesource; try { imagesource = await handler.LoadImageAsync(source); } catch (OperationCanceledException) { imagesource = null; } // 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; Element?.SetValueCore(Image.IsLoadingPropertyKey, false); } } }