diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/CachingStrategy.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/CachingStrategy.cs new file mode 100644 index 00000000000..9db1d3e1ed6 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/CachingStrategy.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Controls +{ + /// + /// The type of caching to be applied to . + /// Default is + /// + public enum ImageExCachingStrategy + { + /// + /// Caching is handled by 's custom caching system. + /// + Custom, + + /// + /// Caching is handled internally by UWP. + /// + Internal + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Members.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Members.cs index dd498b861f5..9e4d53bba97 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Members.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Members.cs @@ -45,6 +45,11 @@ public partial class ImageExBase /// public static readonly DependencyProperty IsCacheEnabledProperty = DependencyProperty.Register(nameof(IsCacheEnabled), typeof(bool), typeof(ImageExBase), new PropertyMetadata(false)); + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty CachingStrategyProperty = DependencyProperty.Register(nameof(CachingStrategy), typeof(ImageExCachingStrategy), typeof(ImageExBase), new PropertyMetadata(ImageExCachingStrategy.Custom)); + /// /// Returns a mask that represents the alpha channel of an image as a /// @@ -125,5 +130,14 @@ public bool IsCacheEnabled get { return (bool)GetValue(IsCacheEnabledProperty); } set { SetValue(IsCacheEnabledProperty, value); } } + + /// + /// Gets or sets a value indicating how the will be cached. + /// + public ImageExCachingStrategy CachingStrategy + { + get { return (ImageExCachingStrategy)GetValue(CachingStrategyProperty); } + set { SetValue(CachingStrategyProperty, value); } + } } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Source.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Source.cs index bf654605a75..90826b23de0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Source.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageExBase.Source.cs @@ -121,60 +121,78 @@ private async Task LoadImageAsync(Uri imageUri) { if (_uri != null) { - if (IsCacheEnabled && _isHttpSource) + if (IsCacheEnabled) { - try + switch (CachingStrategy) { - var propValues = new List>(); - - if (DecodePixelHeight > 0) - { - propValues.Add(new KeyValuePair(nameof(DecodePixelHeight), DecodePixelHeight)); - } - - if (DecodePixelWidth > 0) - { - propValues.Add(new KeyValuePair(nameof(DecodePixelWidth), DecodePixelWidth)); - } - - if (propValues.Count > 0) - { - propValues.Add(new KeyValuePair(nameof(DecodePixelType), DecodePixelType)); - } - - var img = await ImageCache.Instance.GetFromCacheAsync(imageUri, true, _tokenSource.Token, propValues); - - lock (LockObj) - { - // If you have many imageEx in a virtualized listview for instance - // controls will be recycled and the uri will change while waiting for the previous one to load - if (_uri == imageUri) - { - AttachSource(img); - ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs()); - VisualStateManager.GoToState(this, LoadedState, true); - } - } + case ImageExCachingStrategy.Custom when _isHttpSource: + await SetHttpSourceCustomCached(imageUri); + break; + case ImageExCachingStrategy.Custom: + case ImageExCachingStrategy.Internal: + default: + AttachSource(new BitmapImage(imageUri)); + break; } - catch (OperationCanceledException) + } + else + { + AttachSource(new BitmapImage(_uri) { - // nothing to do as cancellation has been requested. - } - catch (Exception e) + CreateOptions = BitmapCreateOptions.IgnoreImageCache + }); + } + } + } + + private async Task SetHttpSourceCustomCached(Uri imageUri) + { + try + { + var propValues = new List>(); + + if (DecodePixelHeight > 0) + { + propValues.Add(new KeyValuePair(nameof(DecodePixelHeight), DecodePixelHeight)); + } + + if (DecodePixelWidth > 0) + { + propValues.Add(new KeyValuePair(nameof(DecodePixelWidth), DecodePixelWidth)); + } + + if (propValues.Count > 0) + { + propValues.Add(new KeyValuePair(nameof(DecodePixelType), DecodePixelType)); + } + + var img = await ImageCache.Instance.GetFromCacheAsync(imageUri, true, _tokenSource.Token, propValues); + + lock (LockObj) + { + // If you have many imageEx in a virtualized listview for instance + // controls will be recycled and the uri will change while waiting for the previous one to load + if (_uri == imageUri) { - lock (LockObj) - { - if (_uri == imageUri) - { - ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e)); - VisualStateManager.GoToState(this, FailedState, true); - } - } + AttachSource(img); + ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs()); + VisualStateManager.GoToState(this, LoadedState, true); } } - else + } + catch (OperationCanceledException) + { + // nothing to do as cancellation has been requested. + } + catch (Exception e) + { + lock (LockObj) { - AttachSource(new BitmapImage(_uri)); + if (_uri == imageUri) + { + ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e)); + VisualStateManager.GoToState(this, FailedState, true); + } } } } diff --git a/docs/controls/ImageEx.md b/docs/controls/ImageEx.md index 00fa73bf0e6..d02de0dec03 100644 --- a/docs/controls/ImageEx.md +++ b/docs/controls/ImageEx.md @@ -8,7 +8,7 @@ keywords: windows 10, uwp, windows community toolkit, uwp community toolkit, uwp # ImageEx XAML Control The [ImageEx Control](https://docs.microsoft.com/dotnet/api/microsoft.toolkit.uwp.ui.controls.imageex) and [RoundImageEx Control](https://docs.microsoft.com/dotnet/api/microsoft.toolkit.uwp.ui.controls.roundimageex) downloads images asynchronously, while showing a loading indicator. Source images are then stored in the application's local cache to preserve resources and load time. ImageEx also extends the default *Image* and *ImageBrush* Platform controls respectively to improve performance through caching. You can also use a placeholder image that will be displayed while loading the main image. - + ## Syntax ```xaml @@ -33,6 +33,8 @@ On Windows 10.0.16299.0 or higher, `CornerRadius` is supported on ImageEx. Use | Property | Type | Description | | -- | -- | -- | | NineGrid | Thickness | Gets or sets the nine-grid used by the image | +| IsCacheEnabled | bool | Gets or sets a value indicating whether gets or sets cache state | +| ImageExCachingStrategy | enum | Gets or sets a value indicating how the Image will be cached | ## RoundImageEx Properties