Load an external image in a universal app

When I was playing with a Universal App, an app with code shared between Windows Phone 8.1 and Windows 8.1, I noticed that loading an image from an externel source isn’t as easy as it should be.
What seems logical is:

View:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image VerticalAlignment="Center" Stretch="UniformToFill" Source="{Binding TheImage}"/>
 
    </Grid>

ViewModel:

        private BitmapImage _TheImage
        public BitmapImage TheImage
        {
            get
            {
                return _TheImage;
            }
 
            private set
            {
                if (_TheImage!= value)
                {
                    _TheImage= value;
 
                    NotifyPropertyChanged("TheImage");
                }
            }
        }
 
        public void LoadImage()
        {
             this.TheImage = new BitmapImage(new Uri("http://www.feron.it/images/Apestaartje.png", UriKind.Relative));
 
        }

After you call the LoadImage method, the image in the grid stays awfully empty. It took serval partial solution that I had to put together to solve this problem and be able to load the image from my server. We need to create a function that loads the images and creates the bitmap. The view isn’t modified.

Viewmodel:

        private WriteableBitmap _TheImage
        public WriteableBitmap TheImage
        {
            get
            {
                return _TheImage;
            }
 
            private set
            {
                if (_TheImage!= value)
                {
                    _TheImage= value;
 
                    NotifyPropertyChanged("TheImage");
                }
            }
        }
 
        async public void LoadImage()
        {
             this.TheImage= await GetWebImageByUrl("http://www.feron.it/images/Apestaartje.png");
        }
 
        public static async Task<BitmapImage> GetWebImageByUrl(string imageUrl)
        {
            HttpClient client = new HttpClient();
            var byteArray = await client.GetByteArrayAsync(imageUrl);
            BitmapImage bitmapImage = new BitmapImage();
            using (MemoryStream ms = new MemoryStream(byteArray))
            {
                try
                {
                    await bitmapImage.SetSourceAsync(ms.AsRandomAccessStream());
                }
                catch (Exception e)
                { 
                }
            }
            return bitmapImage;
        }

As you can see the LoadImage method is not async so it won’t block the UI thread. When this method is called the image is correctly loaded and displayed, remember to require the “Internet (client & server)” capability, otherwise you’ll get an “access denied” error.

Comments are closed.