diff --git a/AsyncImageLoader.Avalonia.Demo/Converters/GetClassNameConverter.cs b/AsyncImageLoader.Avalonia.Demo/Converters/GetClassNameConverter.cs new file mode 100644 index 0000000..3f784f3 --- /dev/null +++ b/AsyncImageLoader.Avalonia.Demo/Converters/GetClassNameConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Globalization; +using Avalonia.Data.Converters; + +namespace AsyncImageLoader.Avalonia.Demo.Converters; + +public class GetClassNameConverter : IValueConverter { + public static GetClassNameConverter Instance { get; } = new(); + + /// + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { + if (value is null) { + return "null"; + } + + return value.GetType().Name; + } + + /// + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { + throw new NotSupportedException(); + } +} \ No newline at end of file diff --git a/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml b/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml index 72756c4..f933f2b 100644 --- a/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml +++ b/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml @@ -4,9 +4,10 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia" xmlns:services="clr-namespace:AsyncImageLoader.Avalonia.Demo.Services" - mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:converters="clr-namespace:AsyncImageLoader.Avalonia.Demo.Converters" + mc:Ignorable="d" d:DesignWidth="800" x:Class="AsyncImageLoader.Avalonia.Demo.Pages.AdvancedImagePage"> - @@ -60,8 +61,32 @@ - + + + + + + You can set CurrentImage property by youself. This sets Source back to null. + + + + Source: + + + + CurrentImage: + + + + + + + + \ No newline at end of file diff --git a/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml.cs b/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml.cs index 8036d0d..5e6148f 100644 --- a/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml.cs +++ b/AsyncImageLoader.Avalonia.Demo/Pages/AdvancedImagePage.axaml.cs @@ -1,7 +1,10 @@ -using Avalonia; +using System; +using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; +using Avalonia.Media.Imaging; +using Avalonia.Platform; namespace AsyncImageLoader.Avalonia.Demo.Pages { public partial class AdvancedImagePage : UserControl { @@ -9,14 +12,18 @@ public AdvancedImagePage() { InitializeComponent(); } - private void InitializeComponent() { - AvaloniaXamlLoader.Load(this); - } - private void ReloadButton_OnClick(object? sender, RoutedEventArgs e) { - var advancedImage = this.FindControl("ReloadableAdvancedImage"); - advancedImage.Source = null; - advancedImage.Source = "https://github.com/AvaloniaUtils/AsyncImageLoader.Avalonia/raw/master/AsyncImageLoader.Avalonia.Demo/Assets/cat0.jpg"; + ReloadableAdvancedImage.Source = null; + ReloadableAdvancedImage.Source = "https://github.com/AvaloniaUtils/AsyncImageLoader.Avalonia/raw/master/AsyncImageLoader.Avalonia.Demo/Assets/cat0.jpg"; + } + + private void SetSourceButton_OnClick(object? sender, RoutedEventArgs e) { + CurrentImageExample.Source = "/Assets/cat5.jpg"; + } + + private void SetCurrentImageButton_OnClick(object? sender, RoutedEventArgs e) { + using var stream = AssetLoader.Open(new Uri("avares://AsyncImageLoader.Avalonia.Demo/Assets/cat4.jpg", UriKind.RelativeOrAbsolute)); + CurrentImageExample.CurrentImage = new Bitmap(stream); } } } \ No newline at end of file diff --git a/AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs b/AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs index 186aeb8..5c35611 100644 --- a/AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs +++ b/AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs @@ -142,7 +142,7 @@ public bool IsLoading public IImage? CurrentImage { get => _currentImage; - private set => SetAndRaise(CurrentImageProperty, ref _currentImage, value); + set => SetAndRaise(CurrentImageProperty, ref _currentImage, value); } /// @@ -169,16 +169,31 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang UpdateImage(change.GetNewValue(), Loader); else if (change.Property == LoaderProperty && ShouldLoaderChangeTriggerUpdate) UpdateImage(change.GetNewValue(), Loader); + else if (change.Property == CurrentImageProperty) + ClearSourceIfUserProvideImage(); else if (change.Property == CornerRadiusProperty) UpdateCornerRadius(change.GetNewValue()); else if (change.Property == BoundsProperty && CornerRadius != default) UpdateCornerRadius(CornerRadius); base.OnPropertyChanged(change); } + private void ClearSourceIfUserProvideImage() { + if (CurrentImage is not null and not ImageWrapper) { + // User provided image himself + Source = null; + } + } + private async void UpdateImage(string? source, IAsyncImageLoader? loader) { _updateCancellationToken?.Cancel(); _updateCancellationToken?.Dispose(); + _updateCancellationToken = null; + if (source is null && CurrentImage is not ImageWrapper) { + // User provided image himself + return; + } + var cancellationTokenSource = _updateCancellationToken = new CancellationTokenSource(); IsLoading = true; CurrentImage = null; @@ -219,8 +234,8 @@ private async void UpdateImage(string? source, IAsyncImageLoader? loader) if (cancellationTokenSource.IsCancellationRequested) return; - CurrentImage = bitmap; - IsLoading = false; + CurrentImage = bitmap is null ? null : new ImageWrapper(bitmap); + IsLoading = false; } private void UpdateCornerRadius(CornerRadius radius) @@ -280,4 +295,18 @@ protected override Size ArrangeOverride(Size finalSize) ? Stretch.CalculateSize(finalSize, CurrentImage.Size) : base.ArrangeOverride(finalSize); } + + public sealed class ImageWrapper : IImage { + public IImage ImageImplementation { get; } + internal ImageWrapper(IImage imageImplementation) { + ImageImplementation = imageImplementation; + } + /// + public void Draw(DrawingContext context, Rect sourceRect, Rect destRect) { + ImageImplementation.Draw(context, sourceRect, destRect); + } + + /// + public Size Size => ImageImplementation.Size; + } } \ No newline at end of file