diff options
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT/ImageRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.WinRT/ImageRenderer.cs | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs new file mode 100644 index 00000000..47c674c7 --- /dev/null +++ b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs @@ -0,0 +1,132 @@ +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<Image, Windows.UI.Xaml.Controls.Image> + { + 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<Image> 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<IImageSourceHandler>(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); + } + } +}
\ No newline at end of file |