diff --git a/src/AppStudio.DataProviders/Core/HttpRequest.cs b/src/AppStudio.DataProviders/Core/HttpRequest.cs index 5aaa045b..c96e137e 100644 --- a/src/AppStudio.DataProviders/Core/HttpRequest.cs +++ b/src/AppStudio.DataProviders/Core/HttpRequest.cs @@ -142,9 +142,12 @@ private async static Task SetRssEncoding(HttpResponseMessage response) { response.Content.Headers.ContentType.CharSet = charset; } - } } + else + { + SetEncoding(response); + } } } diff --git a/src/AppStudio.Uwp/AppStudio.Uwp.csproj b/src/AppStudio.Uwp/AppStudio.Uwp.csproj index fc7646c4..e946bc6c 100644 --- a/src/AppStudio.Uwp/AppStudio.Uwp.csproj +++ b/src/AppStudio.Uwp/AppStudio.Uwp.csproj @@ -187,6 +187,7 @@ + diff --git a/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Members.cs b/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Members.cs index 7b2c5be3..40bf4493 100644 --- a/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Members.cs +++ b/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Members.cs @@ -2,11 +2,15 @@ using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Controls; using Windows.Media.Casting; +using System; +using AppStudio.Uwp.EventArguments; namespace AppStudio.Uwp.Controls { partial class ImageEx { + public event EventHandler ImageFailed; + #region Stretch public Stretch Stretch { diff --git a/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Source.cs b/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Source.cs index 8ab18edc..7989e307 100644 --- a/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Source.cs +++ b/src/AppStudio.Uwp/Controls/ImageEx/ImageEx.Source.cs @@ -1,265 +1,268 @@ -using System; -using System.IO; - -using Windows.UI.Xaml; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Media.Imaging; - -namespace AppStudio.Uwp.Controls -{ - partial class ImageEx - { - private bool _isHttpSource = false; - - #region Source - public object Source - { - get { return (object)GetValue(SourceProperty); } - set { SetValue(SourceProperty, value); } - } - - private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var control = d as ImageEx; - control.SetSource(e.NewValue); - } - - public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(object), typeof(ImageEx), new PropertyMetadata(null, SourceChanged)); - #endregion - - #region SetSource - private void SetSource(object source) - { - _isHttpSource = false; - if (source != null) - { - string url = source as String; - if (url != null) - { - SetSourceString(url); - } - else - { - Uri uri = source as Uri; - if (uri != null) - { - SetSourceUri(uri); - } - else - { - ImageSource imageSource = source as ImageSource; - if (imageSource != null) - { - SetImage(imageSource); - } - else - { - ClearImage(); - ClearImageGif(); - } - } - } - } - else - { - ClearImage(); - ClearImageGif(); - } - } - - private void SetSourceString(string url) - { - Uri uri = null; - if (Uri.TryCreate(url, UriKind.Absolute, out uri)) - { - SetSourceUri(uri); - } - else if (Uri.IsWellFormedUriString(url, UriKind.Relative)) - { - if (Uri.TryCreate("ms-appx:///" + url.TrimStart('/'), UriKind.Absolute, out uri)) - { - SetSourceUri(uri); - } - else - { - ClearImage(); - ClearImageGif(); - } - } - else - { - ClearImage(); - ClearImageGif(); - } - } - - private Uri _currentUri = null; - - private async void SetSourceUri(Uri uri) - { - _currentUri = uri; - try - { - if (uri.IsAbsoluteUri) - { - var cachedUri = uri; - if (uri.Scheme == "http" || uri.Scheme == "https") - { - SetProgress(); - _isHttpSource = true; - if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) - { - cachedUri = await BitmapCache.GetImageUriAsync(uri, (int)_currentSize.Width, (int)_currentSize.Height); - if (cachedUri == null) - { - ClearProgress(); - ClearImage(); - ClearImageGif(); - return; - } - } - } - if (Path.GetExtension(uri.LocalPath).Equals(".gif", StringComparison.OrdinalIgnoreCase)) - { - this.SetImageGif(cachedUri); - } - else - { - this.SetImage(new BitmapImage(cachedUri)); - } - } - else - { - ClearImage(); - ClearImageGif(); - } - } - catch - { - // Invalid Uri - ClearImage(); - ClearImageGif(); - } - } - #endregion - - private async void RefreshSourceUri(Uri uri) - { - try - { - if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) - { - uri = await BitmapCache.GetImageUriAsync(uri, (int)_currentSize.Width, (int)_currentSize.Height); - } - if (uri != null) - { - this.SetImage(new BitmapImage(uri)); - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine("RefreshSourceUri. {0}", ex.Message); - } - } - - private static int _progressCount = 0; - private object _progressCountLock = new object(); - - private void SetProgress() - { - if (this.Progress != null) - { - return; - } - - bool available = false; - - lock (_progressCountLock) - { - if (_progressCount < 100) - { - _progressCount++; - available = true; - } - } - - if (available) - { - var progress = new ProgressRing - { - IsActive = true - }; - progress.SetBinding(ProgressRing.BackgroundProperty, new Binding { Source = this, Path = new PropertyPath("Background") }); - progress.SetBinding(ProgressRing.ForegroundProperty, new Binding { Source = this, Path = new PropertyPath("Foreground") }); - this.Content = progress; - } - } - - private void SetImage(ImageSource imageSource) - { - ClearProgress(); - ClearImageGif(); - - var image = this.Image; - if (image == null) - { - image = new Image(); - image.SetBinding(Image.StretchProperty, new Binding { Source = this, Path = new PropertyPath("Stretch") }); - image.SetBinding(Image.HorizontalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("HorizontalAlignment") }); - image.SetBinding(Image.VerticalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("VerticalAlignment") }); - image.SetBinding(Image.NineGridProperty, new Binding { Source = this, Path = new PropertyPath("NineGrid") }); - this.Content = image; - } - image.Source = imageSource; - } - - private void SetImageGif(Uri uri) - { - ClearProgress(); - ClearImage(); - ClearImageGif(); - - var imageGif = new GifControl(); - imageGif.SetBinding(GifControl.StretchProperty, new Binding { Source = this, Path = new PropertyPath("Stretch") }); - imageGif.SetBinding(GifControl.HorizontalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("HorizontalAlignment") }); - imageGif.SetBinding(GifControl.VerticalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("VerticalAlignment") }); - imageGif.SetBinding(GifControl.NineGridProperty, new Binding { Source = this, Path = new PropertyPath("NineGrid") }); - imageGif.SetBinding(GifControl.AutoPlayProperty, new Binding { Source = this, Path = new PropertyPath("AnimateGif") }); - imageGif.Source = uri; - this.Content = imageGif; - } - - private void ClearProgress() - { - if (this.Progress != null) - { - this.Progress.IsActive = false; - this.Content = null; - lock (_progressCountLock) - { - _progressCount--; - } - } - } - - private void ClearImage() - { - if (this.Image != null) - { - this.Image.Source = null; - this.Content = null; - } - } - - private void ClearImageGif() - { - if (this.ImageGif != null) - { - this.ImageGif.Source = null; - this.Content = null; - } - } - } -} +using System; +using System.IO; + +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media.Imaging; +using AppStudio.Uwp.EventArguments; + +namespace AppStudio.Uwp.Controls +{ + partial class ImageEx + { + private bool _isHttpSource = false; + + #region Source + public object Source + { + get { return (object)GetValue(SourceProperty); } + set { SetValue(SourceProperty, value); } + } + + private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as ImageEx; + control.SetSource(e.NewValue); + } + + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(object), typeof(ImageEx), new PropertyMetadata(null, SourceChanged)); + #endregion + + #region SetSource + private void SetSource(object source) + { + _isHttpSource = false; + if (source != null) + { + string url = source as String; + if (url != null) + { + SetSourceString(url); + } + else + { + Uri uri = source as Uri; + if (uri != null) + { + SetSourceUri(uri); + } + else + { + ImageSource imageSource = source as ImageSource; + if (imageSource != null) + { + SetImage(imageSource); + } + else + { + ClearImage(); + ClearImageGif(); + } + } + } + } + else + { + ClearImage(); + ClearImageGif(); + } + } + + private void SetSourceString(string url) + { + Uri uri = null; + if (Uri.TryCreate(url, UriKind.Absolute, out uri)) + { + SetSourceUri(uri); + } + else if (Uri.IsWellFormedUriString(url, UriKind.Relative)) + { + if (Uri.TryCreate("ms-appx:///" + url.TrimStart('/'), UriKind.Absolute, out uri)) + { + SetSourceUri(uri); + } + else + { + ClearImage(); + ClearImageGif(); + } + } + else + { + ClearImage(); + ClearImageGif(); + } + } + + private Uri _currentUri = null; + + private async void SetSourceUri(Uri uri) + { + _currentUri = uri; + try + { + if (uri.IsAbsoluteUri) + { + var cachedUri = uri; + if (uri.Scheme == "http" || uri.Scheme == "https") + { + SetProgress(); + _isHttpSource = true; + if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) + { + cachedUri = await BitmapCache.GetImageUriAsync(uri, (int)_currentSize.Width, (int)_currentSize.Height); + if (cachedUri == null) + { + ClearProgress(); + ClearImage(); + ClearImageGif(); + + ImageFailed?.Invoke(this, new SourceEventArgs(uri.ToString())); + return; + } + } + } + if (Path.GetExtension(uri.LocalPath).Equals(".gif", StringComparison.OrdinalIgnoreCase)) + { + this.SetImageGif(cachedUri); + } + else + { + this.SetImage(new BitmapImage(cachedUri)); + } + } + else + { + ClearImage(); + ClearImageGif(); + } + } + catch + { + // Invalid Uri + ClearImage(); + ClearImageGif(); + } + } + #endregion + + private async void RefreshSourceUri(Uri uri) + { + try + { + if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled) + { + uri = await BitmapCache.GetImageUriAsync(uri, (int)_currentSize.Width, (int)_currentSize.Height); + } + if (uri != null) + { + this.SetImage(new BitmapImage(uri)); + } + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("RefreshSourceUri. {0}", ex.Message); + } + } + + private static int _progressCount = 0; + private object _progressCountLock = new object(); + + private void SetProgress() + { + if (this.Progress != null) + { + return; + } + + bool available = false; + + lock (_progressCountLock) + { + if (_progressCount < 100) + { + _progressCount++; + available = true; + } + } + + if (available) + { + var progress = new ProgressRing + { + IsActive = true + }; + progress.SetBinding(ProgressRing.BackgroundProperty, new Binding { Source = this, Path = new PropertyPath("Background") }); + progress.SetBinding(ProgressRing.ForegroundProperty, new Binding { Source = this, Path = new PropertyPath("Foreground") }); + this.Content = progress; + } + } + + private void SetImage(ImageSource imageSource) + { + ClearProgress(); + ClearImageGif(); + + var image = this.Image; + if (image == null) + { + image = new Image(); + image.SetBinding(Image.StretchProperty, new Binding { Source = this, Path = new PropertyPath("Stretch") }); + image.SetBinding(Image.HorizontalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("HorizontalAlignment") }); + image.SetBinding(Image.VerticalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("VerticalAlignment") }); + image.SetBinding(Image.NineGridProperty, new Binding { Source = this, Path = new PropertyPath("NineGrid") }); + this.Content = image; + } + image.Source = imageSource; + } + + private void SetImageGif(Uri uri) + { + ClearProgress(); + ClearImage(); + ClearImageGif(); + + var imageGif = new GifControl(); + imageGif.SetBinding(GifControl.StretchProperty, new Binding { Source = this, Path = new PropertyPath("Stretch") }); + imageGif.SetBinding(GifControl.HorizontalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("HorizontalAlignment") }); + imageGif.SetBinding(GifControl.VerticalAlignmentProperty, new Binding { Source = this, Path = new PropertyPath("VerticalAlignment") }); + imageGif.SetBinding(GifControl.NineGridProperty, new Binding { Source = this, Path = new PropertyPath("NineGrid") }); + imageGif.SetBinding(GifControl.AutoPlayProperty, new Binding { Source = this, Path = new PropertyPath("AnimateGif") }); + imageGif.Source = uri; + this.Content = imageGif; + } + + private void ClearProgress() + { + if (this.Progress != null) + { + this.Progress.IsActive = false; + this.Content = null; + lock (_progressCountLock) + { + _progressCount--; + } + } + } + + private void ClearImage() + { + if (this.Image != null) + { + this.Image.Source = null; + this.Content = null; + } + } + + private void ClearImageGif() + { + if (this.ImageGif != null) + { + this.ImageGif.Source = null; + this.Content = null; + } + } + } +} diff --git a/src/AppStudio.Uwp/EventArguments/SourceEventArgs.cs b/src/AppStudio.Uwp/EventArguments/SourceEventArgs.cs new file mode 100644 index 00000000..6f396f3a --- /dev/null +++ b/src/AppStudio.Uwp/EventArguments/SourceEventArgs.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AppStudio.Uwp.EventArguments +{ + public class SourceEventArgs : EventArgs + { + public string Source { get; } + public SourceEventArgs(string source) + { + Source = source; + } + } +} diff --git a/tests/AppStudio.DataProviders.Test.WP81/AppStudio.DataProviders.Test.WP81_TemporaryKey.pfx b/tests/AppStudio.DataProviders.Test.WP81/AppStudio.DataProviders.Test.WP81_TemporaryKey.pfx index 7a9a5b25..191c844f 100644 Binary files a/tests/AppStudio.DataProviders.Test.WP81/AppStudio.DataProviders.Test.WP81_TemporaryKey.pfx and b/tests/AppStudio.DataProviders.Test.WP81/AppStudio.DataProviders.Test.WP81_TemporaryKey.pfx differ diff --git a/tests/AppStudio.DataProviders.Test.Win10/AppStudio.DataProviders.Test.Win10_TemporaryKey.pfx b/tests/AppStudio.DataProviders.Test.Win10/AppStudio.DataProviders.Test.Win10_TemporaryKey.pfx index 7a9a5b25..191c844f 100644 Binary files a/tests/AppStudio.DataProviders.Test.Win10/AppStudio.DataProviders.Test.Win10_TemporaryKey.pfx and b/tests/AppStudio.DataProviders.Test.Win10/AppStudio.DataProviders.Test.Win10_TemporaryKey.pfx differ diff --git a/tests/AppStudio.DataProviders.Test.Win81/AppStudio.DataProviders.Test.Win81_TemporaryKey.pfx b/tests/AppStudio.DataProviders.Test.Win81/AppStudio.DataProviders.Test.Win81_TemporaryKey.pfx index 7a9a5b25..191c844f 100644 Binary files a/tests/AppStudio.DataProviders.Test.Win81/AppStudio.DataProviders.Test.Win81_TemporaryKey.pfx and b/tests/AppStudio.DataProviders.Test.Win81/AppStudio.DataProviders.Test.Win81_TemporaryKey.pfx differ