diff --git a/ImageEx/ImageEx.Members.cs b/ImageEx/ImageEx.Members.cs
index 2535fd6..d223342 100644
--- a/ImageEx/ImageEx.Members.cs
+++ b/ImageEx/ImageEx.Members.cs
@@ -2,40 +2,41 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
-
-///
-/// The ImageEx control extends the default Image platform control improving the performance and responsiveness of your Apps.
-/// Source images are downloaded asynchronously showing a load indicator while in progress.
-/// Once downloaded, the source image is stored in the App local cache to preserve resources and load time next time the image needs to be displayed.
-///
-public partial class ImageEx
+namespace ImageEx
{
///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty NineGridProperty = DependencyProperty.Register(nameof(NineGrid), typeof(Thickness), typeof(ImageEx), new PropertyMetadata(default(Thickness)));
-
- ///
- /// Gets or sets the nine-grid used by the image.
+ /// The ImageEx control extends the default Image platform control improving the performance and responsiveness of your Apps.
+ /// Source images are downloaded asynchronously showing a load indicator while in progress.
+ /// Once downloaded, the source image is stored in the App local cache to preserve resources and load time next time the image needs to be displayed.
///
- public Thickness NineGrid
+ public partial class ImageEx
{
- get { return (Thickness)GetValue(NineGridProperty); }
- set { SetValue(NineGridProperty, value); }
- }
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty NineGridProperty = DependencyProperty.Register(nameof(NineGrid), typeof(Thickness), typeof(ImageEx), new PropertyMetadata(default(Thickness)));
- ///
- /// Returns the image as a .
- ///
- /// The image as a .
- public CastingSource GetAsCastingSource()
- {
- if (IsInitialized && Image is Image image)
+ ///
+ /// Gets or sets the nine-grid used by the image.
+ ///
+ public Thickness NineGrid
{
- return image.GetAsCastingSource();
+ get { return (Thickness)GetValue(NineGridProperty); }
+ set { SetValue(NineGridProperty, value); }
}
- return null;
+ ///
+ /// Returns the image as a .
+ ///
+ /// The image as a .
+ public CastingSource GetAsCastingSource()
+ {
+ if (IsInitialized && Image is Image image)
+ {
+ return image.GetAsCastingSource();
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageEx.cs b/ImageEx/ImageEx.cs
index 0ad9a43..1a20c18 100644
--- a/ImageEx/ImageEx.cs
+++ b/ImageEx/ImageEx.cs
@@ -2,20 +2,25 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
+using System.Diagnostics;
-///
-/// The ImageEx control extends the default Image platform control improving the performance and responsiveness of your Apps.
-/// Source images are downloaded asynchronously showing a load indicator while in progress.
-/// Once downloaded, the source image is stored in the App local cache to preserve resources and load time next time the image needs to be displayed.
-///
-public partial class ImageEx : ImageExBase
+namespace ImageEx
{
///
- /// Initializes a new instance of the class.
+ /// The ImageEx control extends the default Image platform control improving the performance and responsiveness of your Apps.
+ /// Source images are downloaded asynchronously showing a load indicator while in progress.
+ /// Once downloaded, the source image is stored in the App local cache to preserve resources and load time next time the image needs to be displayed.
///
- public ImageEx() : base()
+ public partial class ImageEx : ImageExBase
{
- DefaultStyleKey = typeof(ImageEx);
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ImageEx()
+ : base()
+ {
+ DefaultStyleKey = typeof(ImageEx);
+ Debug.WriteLine(DefaultStyleKey.ToString());
+ }
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageEx.csproj b/ImageEx/ImageEx.csproj
index c8be374..ef04ab9 100644
--- a/ImageEx/ImageEx.csproj
+++ b/ImageEx/ImageEx.csproj
@@ -1,18 +1,17 @@
- uap10.0.22621;net8.0-windows10.0.22621
+ uap10.0.19041;net6.0-windows10.0.19041;net7.0-windows10.0.19041;net8.0-windows10.0.19041
10.0.17763.0
Library
False
- 12.0
+ 11.0
NETSDK1023;CA1416
true
embedded
- true
win-x86;win-x64;win-arm64
diff --git a/ImageEx/ImageExBase.Members.cs b/ImageEx/ImageExBase.Members.cs
index 7727cdf..f536ea2 100644
--- a/ImageEx/ImageExBase.Members.cs
+++ b/ImageEx/ImageExBase.Members.cs
@@ -2,155 +2,156 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
-
-///
-/// Base Code for ImageEx
-///
-public partial class ImageExBase
+namespace ImageEx
{
///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty StretchProperty = DependencyProperty.Register(nameof(Stretch), typeof(Stretch), typeof(ImageExBase), new PropertyMetadata(Stretch.Uniform));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty DecodePixelHeightProperty = DependencyProperty.Register(nameof(DecodePixelHeight), typeof(int), typeof(ImageExBase), new PropertyMetadata(0));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty DecodePixelTypeProperty = DependencyProperty.Register(nameof(DecodePixelType), typeof(int), typeof(ImageExBase), new PropertyMetadata(DecodePixelType.Physical));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty DecodePixelWidthProperty = DependencyProperty.Register(nameof(DecodePixelWidth), typeof(int), typeof(ImageExBase), new PropertyMetadata(0));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty IsCacheEnabledProperty = DependencyProperty.Register(nameof(IsCacheEnabled), typeof(bool), typeof(ImageExBase), new PropertyMetadata(false));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty EnableLazyLoadingProperty = DependencyProperty.Register(nameof(EnableLazyLoading), typeof(bool), typeof(ImageExBase), new PropertyMetadata(false, EnableLazyLoadingChanged));
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty LazyLoadingThresholdProperty = DependencyProperty.Register(nameof(LazyLoadingThreshold), typeof(double), typeof(ImageExBase), new PropertyMetadata(default(double), LazyLoadingThresholdChanged));
-
- ///
- /// Event raised if the image failed loading.
- ///
- public event ImageExFailedEventHandler ImageExFailed;
-
- ///
- /// Event raised when the image is successfully loaded and opened.
+ /// Base Code for ImageEx
///
- public event ImageExOpenedEventHandler ImageExOpened;
-
- ///
- /// Event raised when the control is initialized.
- ///
- public event EventHandler ImageExInitialized;
-
- ///
- /// Gets a value indicating whether control has been initialized.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- /// Gets or sets DecodePixelHeight for underlying bitmap
- ///
- public int DecodePixelHeight
- {
- get { return (int)GetValue(DecodePixelHeightProperty); }
- set { SetValue(DecodePixelHeightProperty, value); }
- }
-
- ///
- /// Gets or sets DecodePixelType for underlying bitmap
- ///
- public DecodePixelType DecodePixelType
+ public partial class ImageExBase
{
- get { return (DecodePixelType)GetValue(DecodePixelTypeProperty); }
- set { SetValue(DecodePixelTypeProperty, value); }
- }
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty StretchProperty = DependencyProperty.Register(nameof(Stretch), typeof(Stretch), typeof(ImageExBase), new PropertyMetadata(Stretch.Uniform));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty DecodePixelHeightProperty = DependencyProperty.Register(nameof(DecodePixelHeight), typeof(int), typeof(ImageExBase), new PropertyMetadata(0));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty DecodePixelTypeProperty = DependencyProperty.Register(nameof(DecodePixelType), typeof(int), typeof(ImageExBase), new PropertyMetadata(DecodePixelType.Physical));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty DecodePixelWidthProperty = DependencyProperty.Register(nameof(DecodePixelWidth), typeof(int), typeof(ImageExBase), new PropertyMetadata(0));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty IsCacheEnabledProperty = DependencyProperty.Register(nameof(IsCacheEnabled), typeof(bool), typeof(ImageExBase), new PropertyMetadata(false));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty EnableLazyLoadingProperty = DependencyProperty.Register(nameof(EnableLazyLoading), typeof(bool), typeof(ImageExBase), new PropertyMetadata(false, EnableLazyLoadingChanged));
+
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty LazyLoadingThresholdProperty = DependencyProperty.Register(nameof(LazyLoadingThreshold), typeof(double), typeof(ImageExBase), new PropertyMetadata(default(double), LazyLoadingThresholdChanged));
+
+ ///
+ /// Event raised if the image failed loading.
+ ///
+ public event ImageExFailedEventHandler ImageExFailed;
+
+ ///
+ /// Event raised when the image is successfully loaded and opened.
+ ///
+ public event ImageExOpenedEventHandler ImageExOpened;
+
+ ///
+ /// Event raised when the control is initialized.
+ ///
+ public event EventHandler ImageExInitialized;
+
+ ///
+ /// Gets a value indicating whether control has been initialized.
+ ///
+ public bool IsInitialized { get; private set; }
+
+ ///
+ /// Gets or sets DecodePixelHeight for underlying bitmap
+ ///
+ public int DecodePixelHeight
+ {
+ get { return (int)GetValue(DecodePixelHeightProperty); }
+ set { SetValue(DecodePixelHeightProperty, value); }
+ }
- ///
- /// Gets or sets DecodePixelWidth for underlying bitmap
- ///
- public int DecodePixelWidth
- {
- get { return (int)GetValue(DecodePixelWidthProperty); }
- set { SetValue(DecodePixelWidthProperty, value); }
- }
+ ///
+ /// Gets or sets DecodePixelType for underlying bitmap
+ ///
+ public DecodePixelType DecodePixelType
+ {
+ get { return (DecodePixelType)GetValue(DecodePixelTypeProperty); }
+ set { SetValue(DecodePixelTypeProperty, value); }
+ }
- ///
- /// Gets or sets the stretch behavior of the image
- ///
- public Stretch Stretch
- {
- get { return (Stretch)GetValue(StretchProperty); }
- set { SetValue(StretchProperty, value); }
- }
+ ///
+ /// Gets or sets DecodePixelWidth for underlying bitmap
+ ///
+ public int DecodePixelWidth
+ {
+ get { return (int)GetValue(DecodePixelWidthProperty); }
+ set { SetValue(DecodePixelWidthProperty, value); }
+ }
- ///
- /// Gets or sets a value indicating whether gets or sets cache state
- ///
- public bool IsCacheEnabled
- {
- get { return (bool)GetValue(IsCacheEnabledProperty); }
- set { SetValue(IsCacheEnabledProperty, value); }
- }
+ ///
+ /// Gets or sets the stretch behavior of the image
+ ///
+ public Stretch Stretch
+ {
+ get { return (Stretch)GetValue(StretchProperty); }
+ set { SetValue(StretchProperty, value); }
+ }
- ///
- /// Gets or sets a value indicating whether gets or sets is lazy loading enable. (17763 or higher supported)
- ///
- /// Windows 10 build 17763 or higher required.
- public bool EnableLazyLoading
- {
- get { return (bool)GetValue(EnableLazyLoadingProperty); }
- set { SetValue(EnableLazyLoadingProperty, value); }
- }
+ ///
+ /// Gets or sets a value indicating whether gets or sets cache state
+ ///
+ public bool IsCacheEnabled
+ {
+ get { return (bool)GetValue(IsCacheEnabledProperty); }
+ set { SetValue(IsCacheEnabledProperty, value); }
+ }
- ///
- /// Gets or sets a value indicating the threshold for triggering lazy loading.
- ///
- public double LazyLoadingThreshold
- {
- get { return (double)GetValue(LazyLoadingThresholdProperty); }
- set { SetValue(LazyLoadingThresholdProperty, value); }
- }
+ ///
+ /// Gets or sets a value indicating whether gets or sets is lazy loading enable. (17763 or higher supported)
+ ///
+ /// Windows 10 build 17763 or higher required.
+ public bool EnableLazyLoading
+ {
+ get { return (bool)GetValue(EnableLazyLoadingProperty); }
+ set { SetValue(EnableLazyLoadingProperty, value); }
+ }
- private static void EnableLazyLoadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is ImageExBase control)
+ ///
+ /// Gets or sets a value indicating the threshold for triggering lazy loading.
+ ///
+ public double LazyLoadingThreshold
{
- var value = (bool)e.NewValue;
- if (value)
- {
- control.LayoutUpdated += control.ImageExBase_LayoutUpdated;
+ get { return (double)GetValue(LazyLoadingThresholdProperty); }
+ set { SetValue(LazyLoadingThresholdProperty, value); }
+ }
- control.InvalidateLazyLoading();
- }
- else
+ private static void EnableLazyLoadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is ImageExBase control)
{
- control.LayoutUpdated -= control.ImageExBase_LayoutUpdated;
+ var value = (bool)e.NewValue;
+ if (value)
+ {
+ control.LayoutUpdated += control.ImageExBase_LayoutUpdated;
+
+ control.InvalidateLazyLoading();
+ }
+ else
+ {
+ control.LayoutUpdated -= control.ImageExBase_LayoutUpdated;
+ }
}
}
- }
- private static void LazyLoadingThresholdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is ImageExBase control && control.EnableLazyLoading)
+ private static void LazyLoadingThresholdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- control.InvalidateLazyLoading();
+ if (d is ImageExBase control && control.EnableLazyLoading)
+ {
+ control.InvalidateLazyLoading();
+ }
}
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageExBase.Placeholder.cs b/ImageEx/ImageExBase.Placeholder.cs
index 963fc98..1becfc4 100644
--- a/ImageEx/ImageExBase.Placeholder.cs
+++ b/ImageEx/ImageExBase.Placeholder.cs
@@ -2,68 +2,69 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
-
-///
-/// Base code for ImageEx
-///
-public partial class ImageExBase
+namespace ImageEx
{
///
- /// Identifies the dependency property.
+ /// Base code for ImageEx
///
- public static readonly DependencyProperty PlaceholderSourceProperty = DependencyProperty.Register(
- nameof(PlaceholderSource),
- typeof(ImageSource),
- typeof(ImageExBase),
- new PropertyMetadata(default(ImageSource), PlaceholderSourceChanged));
+ public partial class ImageExBase
+ {
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty PlaceholderSourceProperty = DependencyProperty.Register(
+ nameof(PlaceholderSource),
+ typeof(ImageSource),
+ typeof(ImageExBase),
+ new PropertyMetadata(default(ImageSource), PlaceholderSourceChanged));
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty PlaceholderStretchProperty = DependencyProperty.Register(
- nameof(PlaceholderStretch),
- typeof(Stretch),
- typeof(ImageExBase),
- new PropertyMetadata(default(Stretch)));
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty PlaceholderStretchProperty = DependencyProperty.Register(
+ nameof(PlaceholderStretch),
+ typeof(Stretch),
+ typeof(ImageExBase),
+ new PropertyMetadata(default(Stretch)));
- ///
- /// Gets or sets the placeholder source.
- ///
- ///
- /// The placeholder source.
- ///
- public ImageSource PlaceholderSource
- {
- get { return (ImageSource)GetValue(PlaceholderSourceProperty); }
- set { SetValue(PlaceholderSourceProperty, value); }
- }
+ ///
+ /// Gets or sets the placeholder source.
+ ///
+ ///
+ /// The placeholder source.
+ ///
+ public ImageSource PlaceholderSource
+ {
+ get { return (ImageSource)GetValue(PlaceholderSourceProperty); }
+ set { SetValue(PlaceholderSourceProperty, value); }
+ }
- private static void PlaceholderSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is ImageExBase control)
+ private static void PlaceholderSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- control.OnPlaceholderSourceChanged(e);
+ if (d is ImageExBase control)
+ {
+ control.OnPlaceholderSourceChanged(e);
+ }
}
- }
- ///
- /// Invoked when Placeholder source has changed
- ///
- /// Event args
- protected virtual void OnPlaceholderSourceChanged(DependencyPropertyChangedEventArgs e)
- {
- }
+ ///
+ /// Invoked when Placeholder source has changed
+ ///
+ /// Event args
+ protected virtual void OnPlaceholderSourceChanged(DependencyPropertyChangedEventArgs e)
+ {
+ }
- ///
- /// Gets or sets the placeholder stretch.
- ///
- ///
- /// The placeholder stretch.
- ///
- public Stretch PlaceholderStretch
- {
- get { return (Stretch)GetValue(PlaceholderStretchProperty); }
- set { SetValue(PlaceholderStretchProperty, value); }
+ ///
+ /// Gets or sets the placeholder stretch.
+ ///
+ ///
+ /// The placeholder stretch.
+ ///
+ public Stretch PlaceholderStretch
+ {
+ get { return (Stretch)GetValue(PlaceholderStretchProperty); }
+ set { SetValue(PlaceholderStretchProperty, value); }
+ }
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageExBase.Source.cs b/ImageEx/ImageExBase.Source.cs
index 3df1442..718817c 100644
--- a/ImageEx/ImageExBase.Source.cs
+++ b/ImageEx/ImageExBase.Source.cs
@@ -2,224 +2,240 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
+using System.Diagnostics;
-///
-/// Base code for ImageEx
-///
-public partial class ImageExBase
+namespace ImageEx
{
///
- /// Identifies the dependency property.
+ /// Base code for ImageEx
///
- public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(nameof(Source), typeof(object), typeof(ImageExBase), new PropertyMetadata(null, SourceChanged));
-
- //// Used to track if we get a new request, so we can cancel any potential custom cache loading.
- private CancellationTokenSource _tokenSource;
+ public partial class ImageExBase
+ {
+ ///
+ /// Identifies the dependency property.
+ ///
+ public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(nameof(Source), typeof(object), typeof(ImageExBase), new PropertyMetadata(null, SourceChanged));
- private object _lazyLoadingSource;
+ //// Used to track if we get a new request, so we can cancel any potential custom cache loading.
+ private CancellationTokenSource _tokenSource;
- ///
- /// Gets or sets the source used by the image
- ///
- public object Source
- {
- get { return GetValue(SourceProperty); }
- set { SetValue(SourceProperty, value); }
- }
+ private object _lazyLoadingSource;
- private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is not ImageExBase control)
+ ///
+ /// Gets or sets the source used by the image
+ ///
+ public object Source
{
- return;
+ get { return GetValue(SourceProperty); }
+ set { Debug.WriteLine("test3"); SetValue(SourceProperty, value); }
}
- if (e.OldValue == null || e.NewValue == null || !e.OldValue.Equals(e.NewValue))
+ private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- if (e.NewValue == null || !control.EnableLazyLoading || control._isInViewport)
+ var control = d as ImageExBase;
+
+ if (control == null)
{
- control._lazyLoadingSource = null;
- control.SetSource(e.NewValue);
+ return;
}
- else
+
+ if (e.OldValue == null || e.NewValue == null || !e.OldValue.Equals(e.NewValue))
{
- control._lazyLoadingSource = e.NewValue;
+ if (e.NewValue == null || !control.EnableLazyLoading || control._isInViewport)
+ {
+ control._lazyLoadingSource = null;
+ control.SetSource(e.NewValue);
+ }
+ else
+ {
+ control._lazyLoadingSource = e.NewValue;
+ }
}
}
- }
-
- private static bool IsHttpUri(Uri uri)
- {
- return uri.IsAbsoluteUri && (uri.Scheme == "http" || uri.Scheme == "https");
- }
- ///
- /// Method to call to assign an value to the underlying powering .
- ///
- /// to assign to the image.
- private void AttachSource(ImageSource source)
- {
- // Setting the source at this point should call ImageExOpened/VisualStateManager.GoToState
- // as we register to both the ImageOpened/ImageFailed events of the underlying control.
- // We only need to call those methods if we fail in other cases before we get here.
- if (Image is Image image)
+ private static bool IsHttpUri(Uri uri)
{
- image.Source = source;
- }
- else if (Image is ImageBrush brush)
- {
- brush.ImageSource = source;
+ return uri.IsAbsoluteUri && (uri.Scheme == "http" || uri.Scheme == "https");
}
- if (source == null)
+ ///
+ /// Method to call to assign an value to the underlying powering .
+ ///
+ /// to assign to the image.
+ private void AttachSource(ImageSource source)
{
- VisualStateManager.GoToState(this, UnloadedState, true);
- }
- else if (source is BitmapSource { PixelHeight: > 0, PixelWidth: > 0 })
- {
- VisualStateManager.GoToState(this, LoadedState, true);
- ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
- }
- }
+ // Setting the source at this point should call ImageExOpened/VisualStateManager.GoToState
+ // as we register to both the ImageOpened/ImageFailed events of the underlying control.
+ // We only need to call those methods if we fail in other cases before we get here.
+ if (Image is Image image)
+ {
+ image.Source = source;
+ }
+ else if (Image is ImageBrush brush)
+ {
+ brush.ImageSource = source;
+ }
- private async void SetSource(object source)
- {
- if (!IsInitialized)
- {
- return;
+ if (source == null)
+ {
+ VisualStateManager.GoToState(this, UnloadedState, true);
+ }
+ else if (source is BitmapSource { PixelHeight: > 0, PixelWidth: > 0 })
+ {
+ VisualStateManager.GoToState(this, LoadedState, true);
+ ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
+ }
+ Debug.WriteLine("test4");
}
- _tokenSource?.Cancel();
-
- _tokenSource = new CancellationTokenSource();
-
- AttachSource(null);
-
- if (source == null)
+ private async void SetSource(object source)
{
- return;
- }
+ Debug.WriteLine("test5_1");
+ if (!IsInitialized)
+ {
+ return;
+ }
- VisualStateManager.GoToState(this, LoadingState, true);
+ Debug.WriteLine("test5_2");
+ _tokenSource?.Cancel();
- if (source is ImageSource imageSource)
- {
- AttachSource(imageSource);
- return;
- }
+ _tokenSource = new CancellationTokenSource();
- var uri = source as Uri;
- if (uri == null)
- {
- var url = source as string ?? source.ToString();
- if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
+ AttachSource(null);
+
+ if (source == null)
{
- VisualStateManager.GoToState(this, FailedState, true);
- ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new UriFormatException("Invalid uri specified.")));
return;
}
- }
- if (!IsHttpUri(uri) && !uri.IsAbsoluteUri)
- {
- uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/'));
- }
+ Debug.WriteLine("test5_3");
- try
- {
- await LoadImageAsync(uri, _tokenSource.Token);
- }
- catch (OperationCanceledException)
- {
- // nothing to do as cancellation has been requested.
- }
- catch (Exception e)
- {
- VisualStateManager.GoToState(this, FailedState, true);
- ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e));
- }
- }
+ VisualStateManager.GoToState(this, LoadingState, true);
- private async Task LoadImageAsync(Uri imageUri, CancellationToken token)
- {
- if (imageUri != null)
- {
- if (IsCacheEnabled)
+ var imageSource = source as ImageSource;
+ if (imageSource != null)
{
- var img = await ProvideCachedResourceAsync(imageUri, token);
+ AttachSource(imageSource);
- if (!_tokenSource.IsCancellationRequested)
+ return;
+ }
+ Debug.WriteLine("test5_4");
+ var uri = source as Uri;
+ if (uri == null)
+ {
+ var url = source as string ?? source.ToString();
+ if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
{
- // Only attach our image if we still have a valid request.
- AttachSource(img);
+ VisualStateManager.GoToState(this, FailedState, true);
+ ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new UriFormatException("Invalid uri specified.")));
+ return;
}
}
- else if (string.Equals(imageUri.Scheme, "data", StringComparison.OrdinalIgnoreCase))
+
+ Debug.WriteLine("test5_6");
+ if (!IsHttpUri(uri) && !uri.IsAbsoluteUri)
+ {
+ uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/'));
+ }
+
+ Debug.WriteLine("test5_7");
+ try
+ {
+ await LoadImageAsync(uri, _tokenSource.Token);
+ }
+ catch (OperationCanceledException)
{
- var source = imageUri.OriginalString;
- const string base64Head = "base64,";
- var index = source.IndexOf(base64Head);
- if (index >= 0)
+ // nothing to do as cancellation has been requested.
+ }
+ catch (Exception e)
+ {
+ VisualStateManager.GoToState(this, FailedState, true);
+ ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(e));
+ }
+
+ Debug.WriteLine("test5");
+ }
+
+ private async Task LoadImageAsync(Uri imageUri, CancellationToken token)
+ {
+ if (imageUri != null)
+ {
+ if (IsCacheEnabled)
{
- var bytes = Convert.FromBase64String(source.Substring(index + base64Head.Length));
- var bitmap = new BitmapImage();
- await bitmap.SetSourceAsync(new MemoryStream(bytes).AsRandomAccessStream());
+ var img = await ProvideCachedResourceAsync(imageUri, token);
if (!_tokenSource.IsCancellationRequested)
{
- AttachSource(bitmap);
+ // Only attach our image if we still have a valid request.
+ AttachSource(img);
}
}
- }
- else
- {
- AttachSource(new BitmapImage(imageUri)
+ else if (string.Equals(imageUri.Scheme, "data", StringComparison.OrdinalIgnoreCase))
{
- CreateOptions = BitmapCreateOptions.IgnoreImageCache
- });
+ var source = imageUri.OriginalString;
+ const string base64Head = "base64,";
+ var index = source.IndexOf(base64Head);
+ if (index >= 0)
+ {
+ var bytes = Convert.FromBase64String(source.Substring(index + base64Head.Length));
+ var bitmap = new BitmapImage();
+ await bitmap.SetSourceAsync(new MemoryStream(bytes).AsRandomAccessStream());
+
+ if (!_tokenSource.IsCancellationRequested)
+ {
+ AttachSource(bitmap);
+ }
+ }
+ }
+ else
+ {
+ AttachSource(new BitmapImage(imageUri)
+ {
+ CreateOptions = BitmapCreateOptions.IgnoreImageCache
+ });
+ }
}
}
- }
- ///
- /// This method is provided in case a developer would like their own custom caching strategy for .
- /// By default it uses the built-in UWP cache provided by and
- /// the control itself. This method should return an
- /// value of the image specified by the provided uri parameter.
- /// A is provided in case the current request is invalidated
- /// (e.g. the container is recycled before the original image is loaded).
- /// The Toolkit also has an image cache helper which can be used as well:
- /// in .
- ///
- ///
- ///
- /// var propValues = new List<KeyValuePair<string, object>>();
- ///
- /// if (DecodePixelHeight > 0)
- /// {
- /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelHeight), DecodePixelHeight));
- /// }
- /// if (DecodePixelWidth > 0)
- /// {
- /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelWidth), DecodePixelWidth));
- /// }
- /// if (propValues.Count > 0)
- /// {
- /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelType), DecodePixelType));
- /// }
- ///
- /// // A token is provided here as well to cancel the request to the cache,
- /// // if a new image is requested.
- /// return await ImageCache.Instance.GetFromCacheAsync(imageUri, true, token, propValues);
- ///
- ///
- /// of the image to load from the cache.
- /// A which is used to signal when the current request is outdated.
- ///
- protected virtual Task ProvideCachedResourceAsync(Uri imageUri, CancellationToken token)
- {
- // By default we just use the built-in UWP image cache provided within the Image control.
- return Task.FromResult((ImageSource)new BitmapImage(imageUri));
+ ///
+ /// This method is provided in case a developer would like their own custom caching strategy for .
+ /// By default it uses the built-in UWP cache provided by and
+ /// the control itself. This method should return an
+ /// value of the image specified by the provided uri parameter.
+ /// A is provided in case the current request is invalidated
+ /// (e.g. the container is recycled before the original image is loaded).
+ /// The Toolkit also has an image cache helper which can be used as well:
+ /// in .
+ ///
+ ///
+ ///
+ /// var propValues = new List<KeyValuePair<string, object>>();
+ ///
+ /// if (DecodePixelHeight > 0)
+ /// {
+ /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelHeight), DecodePixelHeight));
+ /// }
+ /// if (DecodePixelWidth > 0)
+ /// {
+ /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelWidth), DecodePixelWidth));
+ /// }
+ /// if (propValues.Count > 0)
+ /// {
+ /// propValues.Add(new KeyValuePair<string, object>(nameof(DecodePixelType), DecodePixelType));
+ /// }
+ ///
+ /// // A token is provided here as well to cancel the request to the cache,
+ /// // if a new image is requested.
+ /// return await ImageCache.Instance.GetFromCacheAsync(imageUri, true, token, propValues);
+ ///
+ ///
+ /// of the image to load from the cache.
+ /// A which is used to signal when the current request is outdated.
+ ///
+ protected virtual Task ProvideCachedResourceAsync(Uri imageUri, CancellationToken token)
+ {
+ // By default we just use the built-in UWP image cache provided within the Image control.
+ return Task.FromResult((ImageSource)new BitmapImage(imageUri));
+ }
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageExBase.cs b/ImageEx/ImageExBase.cs
index 0bdbbbe..f50b9fd 100644
--- a/ImageEx/ImageExBase.cs
+++ b/ImageEx/ImageExBase.cs
@@ -2,254 +2,260 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
+using System.Diagnostics;
-public static class Extensions
+namespace ImageEx
{
- ///
- /// Determines if a rectangle intersects with another rectangle.
- ///
- /// The first rectangle to test.
- /// The second rectangle to test.
- /// This method returns if there is any intersection, otherwise .
- [Pure]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IntersectsWith(this Rect rect1, Rect rect2)
+ public static class Extensions
{
- if (rect1.IsEmpty || rect2.IsEmpty)
+ ///
+ /// Determines if a rectangle intersects with another rectangle.
+ ///
+ /// The first rectangle to test.
+ /// The second rectangle to test.
+ /// This method returns if there is any intersection, otherwise .
+ [Pure]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IntersectsWith(this Rect rect1, Rect rect2)
{
- return false;
- }
-
- return (rect1.Left <= rect2.Right) &&
- (rect1.Right >= rect2.Left) &&
- (rect1.Top <= rect2.Bottom) &&
- (rect1.Bottom >= rect2.Top);
- }
-}
-
-///
-/// Base Code for ImageEx
-///
-[TemplateVisualState(Name = LoadingState, GroupName = CommonGroup)]
-[TemplateVisualState(Name = LoadedState, GroupName = CommonGroup)]
-[TemplateVisualState(Name = UnloadedState, GroupName = CommonGroup)]
-[TemplateVisualState(Name = FailedState, GroupName = CommonGroup)]
-[TemplatePart(Name = PartImage, Type = typeof(object))]
-public abstract partial class ImageExBase : Control
-{
- private bool _isInViewport;
-
- ///
- /// Image name in template
- ///
- protected const string PartImage = "Image";
-
- ///
- /// VisualStates name in template
- ///
- protected const string CommonGroup = "CommonStates";
-
- ///
- /// Loading state name in template
- ///
- protected const string LoadingState = "Loading";
-
- ///
- /// Loaded state name in template
- ///
- protected const string LoadedState = "Loaded";
-
- ///
- /// Unloaded state name in template
- ///
- protected const string UnloadedState = "Unloaded";
-
- ///
- /// Failed name in template
- ///
- protected const string FailedState = "Failed";
-
- ///
- /// Gets the backing image object
- ///
- protected object Image { get; private set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public ImageExBase() { }
+ if (rect1.IsEmpty || rect2.IsEmpty)
+ {
+ return false;
+ }
- ///
- /// Attach image opened event handler
- ///
- /// Routed Event Handler
- protected void AttachImageOpened(RoutedEventHandler handler)
- {
- if (Image is Image image)
- {
- image.ImageOpened += handler;
- }
- else if (Image is ImageBrush brush)
- {
- brush.ImageOpened += handler;
+ return (rect1.Left <= rect2.Right) &&
+ (rect1.Right >= rect2.Left) &&
+ (rect1.Top <= rect2.Bottom) &&
+ (rect1.Bottom >= rect2.Top);
}
}
///
- /// Remove image opened handler
+ /// Base Code for ImageEx
///
- /// RoutedEventHandler
- protected void RemoveImageOpened(RoutedEventHandler handler)
+ [TemplateVisualState(Name = LoadingState, GroupName = CommonGroup)]
+ [TemplateVisualState(Name = LoadedState, GroupName = CommonGroup)]
+ [TemplateVisualState(Name = UnloadedState, GroupName = CommonGroup)]
+ [TemplateVisualState(Name = FailedState, GroupName = CommonGroup)]
+ [TemplatePart(Name = PartImage, Type = typeof(object))]
+ public abstract partial class ImageExBase : Control
{
- if (Image is Image image)
+ private bool _isInViewport;
+
+ ///
+ /// Image name in template
+ ///
+ protected const string PartImage = "Image";
+
+ ///
+ /// VisualStates name in template
+ ///
+ protected const string CommonGroup = "CommonStates";
+
+ ///
+ /// Loading state name in template
+ ///
+ protected const string LoadingState = "Loading";
+
+ ///
+ /// Loaded state name in template
+ ///
+ protected const string LoadedState = "Loaded";
+
+ ///
+ /// Unloaded state name in template
+ ///
+ protected const string UnloadedState = "Unloaded";
+
+ ///
+ /// Failed name in template
+ ///
+ protected const string FailedState = "Failed";
+
+ ///
+ /// Gets the backing image object
+ ///
+ protected object Image { get; private set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ImageExBase()
{
- image.ImageOpened -= handler;
+ Debug.WriteLine("test2");
}
- else if (Image is ImageBrush brush)
+
+ ///
+ /// Attach image opened event handler
+ ///
+ /// Routed Event Handler
+ protected void AttachImageOpened(RoutedEventHandler handler)
{
- brush.ImageOpened -= handler;
+ if (Image is Image image)
+ {
+ image.ImageOpened += handler;
+ }
+ else if (Image is ImageBrush brush)
+ {
+ brush.ImageOpened += handler;
+ }
}
- }
- ///
- /// Attach image failed event handler
- ///
- /// Exception Routed Event Handler
- protected void AttachImageFailed(ExceptionRoutedEventHandler handler)
- {
- if (Image is Image image)
+ ///
+ /// Remove image opened handler
+ ///
+ /// RoutedEventHandler
+ protected void RemoveImageOpened(RoutedEventHandler handler)
{
- image.ImageFailed += handler;
+ if (Image is Image image)
+ {
+ image.ImageOpened -= handler;
+ }
+ else if (Image is ImageBrush brush)
+ {
+ brush.ImageOpened -= handler;
+ }
}
- else if (Image is ImageBrush brush)
+
+ ///
+ /// Attach image failed event handler
+ ///
+ /// Exception Routed Event Handler
+ protected void AttachImageFailed(ExceptionRoutedEventHandler handler)
{
- brush.ImageFailed += handler;
+ if (Image is Image image)
+ {
+ image.ImageFailed += handler;
+ }
+ else if (Image is ImageBrush brush)
+ {
+ brush.ImageFailed += handler;
+ }
}
- }
- ///
- /// Remove Image Failed handler
- ///
- /// Exception Routed Event Handler
- protected void RemoveImageFailed(ExceptionRoutedEventHandler handler)
- {
- if (Image is Image image)
+ ///
+ /// Remove Image Failed handler
+ ///
+ /// Exception Routed Event Handler
+ protected void RemoveImageFailed(ExceptionRoutedEventHandler handler)
{
- image.ImageFailed -= handler;
+ if (Image is Image image)
+ {
+ image.ImageFailed -= handler;
+ }
+ else if (Image is ImageBrush brush)
+ {
+ brush.ImageFailed -= handler;
+ }
}
- else if (Image is ImageBrush brush)
+
+ ///
+ /// Update the visual state of the control when its template is changed.
+ ///
+ protected override void OnApplyTemplate()
{
- brush.ImageFailed -= handler;
- }
- }
+ RemoveImageOpened(OnImageOpened);
+ RemoveImageFailed(OnImageFailed);
- ///
- /// Update the visual state of the control when its template is changed.
- ///
- protected override void OnApplyTemplate()
- {
- RemoveImageOpened(OnImageOpened);
- RemoveImageFailed(OnImageFailed);
+ Image = GetTemplateChild(PartImage) as object;
- Image = GetTemplateChild(PartImage) as object;
+ IsInitialized = true;
- IsInitialized = true;
+ ImageExInitialized?.Invoke(this, EventArgs.Empty);
- ImageExInitialized?.Invoke(this, EventArgs.Empty);
+ if (Source == null || !EnableLazyLoading || _isInViewport)
+ {
+ _lazyLoadingSource = null;
+ SetSource(Source);
+ }
+ else
+ {
+ _lazyLoadingSource = Source;
+ }
- if (Source == null || !EnableLazyLoading || _isInViewport)
- {
- _lazyLoadingSource = null;
- SetSource(Source);
+ AttachImageOpened(OnImageOpened);
+ AttachImageFailed(OnImageFailed);
+
+ base.OnApplyTemplate();
}
- else
+
+ ///
+ /// Underlying event handler.
+ ///
+ /// Image
+ /// Event Arguments
+ protected virtual void OnImageOpened(object sender, RoutedEventArgs e)
{
- _lazyLoadingSource = Source;
+ VisualStateManager.GoToState(this, LoadedState, true);
+ ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
}
- AttachImageOpened(OnImageOpened);
- AttachImageFailed(OnImageFailed);
-
- base.OnApplyTemplate();
- }
-
- ///
- /// Underlying event handler.
- ///
- /// Image
- /// Event Arguments
- protected virtual void OnImageOpened(object sender, RoutedEventArgs e)
- {
- VisualStateManager.GoToState(this, LoadedState, true);
- ImageExOpened?.Invoke(this, new ImageExOpenedEventArgs());
- }
-
- ///
- /// Underlying event handler.
- ///
- /// Image
- /// Event Arguments
- protected virtual void OnImageFailed(object sender, ExceptionRoutedEventArgs e)
- {
- VisualStateManager.GoToState(this, FailedState, true);
- ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new Exception(e.ErrorMessage)));
- }
-
- private void ImageExBase_LayoutUpdated(object sender, object e)
- {
- InvalidateLazyLoading();
- }
+ ///
+ /// Underlying event handler.
+ ///
+ /// Image
+ /// Event Arguments
+ protected virtual void OnImageFailed(object sender, ExceptionRoutedEventArgs e)
+ {
+ VisualStateManager.GoToState(this, FailedState, true);
+ ImageExFailed?.Invoke(this, new ImageExFailedEventArgs(new Exception(e.ErrorMessage)));
+ }
- private void InvalidateLazyLoading()
- {
- if (!IsLoaded)
+ private void ImageExBase_LayoutUpdated(object sender, object e)
{
- _isInViewport = false;
- return;
+ InvalidateLazyLoading();
}
- // Find the first ascendant ScrollViewer, if not found, use the root element.
- FrameworkElement hostElement = null;
- var ascendants = this.FindAscendants().OfType();
- foreach (var ascendant in ascendants)
+ private void InvalidateLazyLoading()
{
- hostElement = ascendant;
- if (hostElement is ScrollViewer)
+ if (!IsLoaded)
{
- break;
+ _isInViewport = false;
+ return;
}
- }
- if (hostElement == null)
- {
- _isInViewport = false;
- return;
- }
+ // Find the first ascendant ScrollViewer, if not found, use the root element.
+ FrameworkElement hostElement = null;
+ var ascendants = this.FindAscendants().OfType();
+ foreach (var ascendant in ascendants)
+ {
+ hostElement = ascendant;
+ if (hostElement is ScrollViewer)
+ {
+ break;
+ }
+ }
- var controlRect = TransformToVisual(hostElement)
- .TransformBounds(new Rect(0, 0, ActualWidth, ActualHeight));
- var lazyLoadingThreshold = LazyLoadingThreshold;
- var hostRect = new Rect(
- 0 - lazyLoadingThreshold,
- 0 - lazyLoadingThreshold,
- hostElement.ActualWidth + (2 * lazyLoadingThreshold),
- hostElement.ActualHeight + (2 * lazyLoadingThreshold));
+ if (hostElement == null)
+ {
+ _isInViewport = false;
+ return;
+ }
- if (controlRect.IntersectsWith(hostRect))
- {
- _isInViewport = true;
+ var controlRect = TransformToVisual(hostElement)
+ .TransformBounds(new Rect(0, 0, ActualWidth, ActualHeight));
+ var lazyLoadingThreshold = LazyLoadingThreshold;
+ var hostRect = new Rect(
+ 0 - lazyLoadingThreshold,
+ 0 - lazyLoadingThreshold,
+ hostElement.ActualWidth + (2 * lazyLoadingThreshold),
+ hostElement.ActualHeight + (2 * lazyLoadingThreshold));
- if (_lazyLoadingSource != null)
+ if (controlRect.IntersectsWith(hostRect))
{
- var source = _lazyLoadingSource;
- _lazyLoadingSource = null;
- SetSource(source);
+ _isInViewport = true;
+
+ if (_lazyLoadingSource != null)
+ {
+ var source = _lazyLoadingSource;
+ _lazyLoadingSource = null;
+ SetSource(source);
+ }
+ }
+ else
+ {
+ _isInViewport = false;
}
- }
- else
- {
- _isInViewport = false;
}
}
}
\ No newline at end of file
diff --git a/ImageEx/ImageExFailedEventArgs.cs b/ImageEx/ImageExFailedEventArgs.cs
index 58c6fec..20089d3 100644
--- a/ImageEx/ImageExFailedEventArgs.cs
+++ b/ImageEx/ImageExFailedEventArgs.cs
@@ -2,37 +2,38 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
-
-///
-/// A delegate for failed.
-///
-/// The sender.
-/// The event arguments.
-public delegate void ImageExFailedEventHandler(object sender, ImageExFailedEventArgs e);
-
-///
-/// Provides data for the ImageFailed event.
-///
-public class ImageExFailedEventArgs : EventArgs
+namespace ImageEx
{
///
- /// Initializes a new instance of the class.
+ /// A delegate for failed.
///
- /// exception that caused the error condition
- public ImageExFailedEventArgs(Exception errorException)
- {
- ErrorException = errorException;
- ErrorMessage = ErrorException?.Message;
- }
+ /// The sender.
+ /// The event arguments.
+ public delegate void ImageExFailedEventHandler(object sender, ImageExFailedEventArgs e);
///
- /// Gets the exception that caused the error condition.
+ /// Provides data for the ImageFailed event.
///
- public Exception ErrorException { get; private set; }
+ public class ImageExFailedEventArgs : EventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// exception that caused the error condition
+ public ImageExFailedEventArgs(Exception errorException)
+ {
+ ErrorException = errorException;
+ ErrorMessage = ErrorException?.Message;
+ }
- ///
- /// Gets the reason for the error condition.
- ///
- public string ErrorMessage { get; private set; }
+ ///
+ /// Gets the exception that caused the error condition.
+ ///
+ public Exception ErrorException { get; private set; }
+
+ ///
+ /// Gets the reason for the error condition.
+ ///
+ public string ErrorMessage { get; private set; }
+ }
}
\ No newline at end of file
diff --git a/ImageEx/ImageExOpenedEventArgs.cs b/ImageEx/ImageExOpenedEventArgs.cs
index 0b8dff7..792adbf 100644
--- a/ImageEx/ImageExOpenedEventArgs.cs
+++ b/ImageEx/ImageExOpenedEventArgs.cs
@@ -2,16 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ImageEx;
+namespace ImageEx
+{
+ ///
+ /// A delegate for opened.
+ ///
+ /// The sender.
+ /// The event arguments.
+ public delegate void ImageExOpenedEventHandler(object sender, ImageExOpenedEventArgs e);
-///
-/// A delegate for opened.
-///
-/// The sender.
-/// The event arguments.
-public delegate void ImageExOpenedEventHandler(object sender, ImageExOpenedEventArgs e);
-
-///
-/// Provides data for the ImageOpened event.
-///
-public class ImageExOpenedEventArgs : EventArgs { }
\ No newline at end of file
+ ///
+ /// Provides data for the ImageOpened event.
+ ///
+ public class ImageExOpenedEventArgs : EventArgs
+ {
+ }
+}
\ No newline at end of file
diff --git a/ImageEx/Properties/AssemblyInfo.cs b/ImageEx/Properties/AssemblyInfo.cs
index 74ba45e..9331db5 100644
--- a/ImageEx/Properties/AssemblyInfo.cs
+++ b/ImageEx/Properties/AssemblyInfo.cs
@@ -4,8 +4,8 @@
[assembly: AssemblyTitle("ImageEx")]
[assembly: AssemblyDescription("Extended Image Control for UWP and WinUI apps")]
[assembly: AssemblyProduct("ImageEx")]
-[assembly: AssemblyCopyright("FourSoft © 2024")]
+[assembly: AssemblyCopyright("FourSoft © 2023")]
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
+[assembly: AssemblyVersion("2.1.0.0")]
+[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: ComVisible(false)]
\ No newline at end of file