In AvaloniaUI, how to display an image from a web URL?

Viewed 1943

I'm developing an Avalonia App using ReactiveUI and MVVM. I want to display an image from a web URL, what would be the best course of action to achieve this ? I have setup the following Binding :

                this.OneWayBind(
                    ViewModel,
                    vm => vm.UserProfileImageUrl,
                    v => v.ProfileImage.Source,
                    ImageConverter
                ).DisposeWith(disposables);

And Binding adapter :

        private IImage ImageConverter(string arg)
        {
        
        }

But I don't know how to implement the Binding adapter to download the image without blocking the UI. Is there some tool like Glide on Android ?

Thank you in advance,

1 Answers

You can download and store the Image in your ViewModel asynchronously, or using the download complete event for example like this:

public class MainWindowViewModel : ViewModelBase
    {
        private string chessboardUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Chess_Board.svg/2000px-Chess_Board.svg.png";
        public string ChessboardUrl
        {
            get => chessboardUrl;
            set {
                this.RaiseAndSetIfChanged(ref chessboardUrl, value);
                DownloadImage(ChessboardUrl);
                System.Diagnostics.Debug.WriteLine(ChessboardUrl);
            }
        }

        private Avalonia.Media.Imaging.Bitmap chessboard = null;
        public Avalonia.Media.Imaging.Bitmap Chessboard
        {
            get => chessboard;
            set => this.RaiseAndSetIfChanged(ref chessboard, value);
        }

        public MainWindowViewModel()
        {
            DownloadImage(ChessboardUrl);
        }

        public void DownloadImage(string url)
        {
            using (WebClient client = new WebClient())
            {
                client.DownloadDataAsync(new Uri(url));
                client.DownloadDataCompleted += DownloadComplete;
            }
        }

        private void DownloadComplete(object sender, DownloadDataCompletedEventArgs e)
        {
            try
            {
                byte[] bytes = e.Result;

                Stream stream = new MemoryStream(bytes);

                var image = new Avalonia.Media.Imaging.Bitmap(stream);
                Chessboard = image;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
                Chessboard = null; // Could not download...
            }
            
        }
    }

Then you can easily bind to the Url and the associated image. For example like this from the XAML (with appropriate DataContext):

<StackPanel>
    <Image Source="{Binding Chessboard}"
           Width="200"
           Height="200"
           Name="MyImage"></Image>
    <TextBox Text="{Binding ChessboardUrl}"></TextBox>
    
</StackPanel>
Related