This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Windows.Networking.Connectivity; | |
using Windows.UI; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Data; | |
using Windows.UI.Xaml.Media; | |
using Windows.UI.Xaml.Media.Imaging; | |
namespace CustomControls | |
{ | |
public class AdaptiveImage : ContentControl | |
{ | |
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( | |
"Source", | |
typeof(AdaptiveImageSource), | |
typeof(AdaptiveImage), | |
new PropertyMetadata(null, OnSourceChanged)); | |
public static readonly DependencyProperty ImageTemplateProperty = DependencyProperty.Register( | |
"ImageTemplate", | |
typeof(DataTemplate), | |
typeof(AdaptiveImage), | |
null); | |
public AdaptiveImage() | |
{ | |
this.LayoutRoot = new Grid(); | |
this.Content = this.LayoutRoot; | |
this.ProgressIndicator = new ProgressRing | |
{ | |
Foreground = new SolidColorBrush { Color = Colors.White }, | |
Width = 100, | |
Height = 100, | |
HorizontalAlignment = HorizontalAlignment.Stretch, | |
VerticalAlignment = VerticalAlignment.Stretch | |
}; | |
} | |
public DataTemplate ImageTemplate | |
{ | |
get { return this.GetValue(ImageTemplateProperty) as DataTemplate; } | |
set { this.SetValue(ImageTemplateProperty, value); } | |
} | |
public AdaptiveImageSource Source | |
{ | |
get { return this.GetValue(SourceProperty) as AdaptiveImageSource; } | |
set { this.SetValue(SourceProperty, value); } | |
} | |
protected Grid LayoutRoot { get; } | |
private FrameworkElement LowResImage { get; set; } | |
private FrameworkElement HiResImage { get; set; } | |
private ProgressRing ProgressIndicator { get; set; } | |
private static void OnSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) | |
{ | |
(sender as AdaptiveImage)?.StartLoading(); | |
} | |
private static bool ShouldLoadHiResolutionPicture() | |
{ | |
var connectionCost = NetworkInformation.GetInternetConnectionProfile()?.GetConnectionCost(); | |
if (connectionCost == null) | |
{ | |
return false; | |
} | |
switch (connectionCost.NetworkCostType) | |
{ | |
case NetworkCostType.Unrestricted: | |
return true; | |
case NetworkCostType.Fixed: | |
case NetworkCostType.Variable: | |
return !connectionCost.ApproachingDataLimit && !connectionCost.OverDataLimit && !connectionCost.Roaming; | |
default: | |
return false; | |
} | |
} | |
private FrameworkElement CreateImage() | |
{ | |
var customElement = this.ImageTemplate?.LoadContent() as FrameworkElement; | |
if (customElement != null) | |
{ | |
return customElement; | |
} | |
var image = new Image(); | |
image.SetBinding(Image.SourceProperty, new Binding()); | |
return image; | |
} | |
private void StartLoading() | |
{ | |
this.LayoutRoot.Children.Clear(); | |
this.LowResImage = null; | |
this.HiResImage = null; | |
var source = this.Source; | |
if (source?.LowResSource == null) | |
{ | |
return; | |
} | |
var lowResSource = new BitmapImage { UriSource = new Uri(source.LowResSource) }; | |
this.LowResImage = this.CreateImage(); | |
this.LowResImage.DataContext = lowResSource; | |
this.LayoutRoot.Children.Add(this.LowResImage); | |
if (source.HiResSource != null && ShouldLoadHiResolutionPicture()) | |
{ | |
this.ProgressIndicator.IsActive = true; | |
this.LayoutRoot.Children.Add(this.ProgressIndicator); | |
var hiResSource = new BitmapImage(); | |
hiResSource.ImageOpened += this.ImageOpened; | |
hiResSource.ImageFailed += this.ImageFailed; | |
hiResSource.UriSource = new Uri(source.HiResSource); | |
this.HiResImage = this.CreateImage(); | |
this.HiResImage.DataContext = hiResSource; | |
this.LayoutRoot.Children.Add(this.HiResImage); | |
this.HiResImage.Visibility = Visibility.Collapsed; | |
} | |
} | |
private void ImageFailed(object sender, ExceptionRoutedEventArgs e) | |
{ | |
this.ProgressIndicator.IsActive = false; | |
} | |
private void ImageOpened(object sender, RoutedEventArgs e) | |
{ | |
if (this.HiResImage != null) | |
{ | |
this.LayoutRoot.Children.Remove(this.LowResImage); | |
this.HiResImage.Visibility = Visibility.Visible; | |
this.ProgressIndicator.IsActive = false; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment