citizen conn
citizen conn

Reputation: 15390

How to bind to an async image source

I would like for instead of the image source to be bound to the Image property of my binding source, but to point to an async method which fetches the image remotely. I need to be able to pass in the two parameters.

Image Fetch

class ConnectImage
{
    public static async Task<BitmapImage> GetImageAsync(Uri uri, String sid)
    {
        HttpClient httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("Authorization", "OAuth " + sid); 

        HttpResponseMessage response = await httpClient.GetAsync(uri);

        BitmapImage bmp = new BitmapImage();
        byte[] byteArray = await response.Content.ReadAsByteArrayAsync();

        InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
        DataWriter writer = new DataWriter(ras.GetOutputStreamAt(0));
        writer.WriteBytes(byteArray);
        BitmapImage image = new BitmapImage();
        image.SetSource(ras);
        return image;
    }
}

ListView

<ListView
        x:Name="itemListView"
        Grid.Row="1"
        ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
        IsSwipeEnabled="False"
        ItemTemplate="{StaticResource FeedItemTemplate}"/>

FeedItemTemplate

<DataTemplate x:Key="FeedItemTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Border Width="110" Height="110">
            <Image Source="{Binding Image}" Stretch="UniformToFill" />
        </Border>
    </Grid>
</DataTemplate>

Upvotes: 2

Views: 3644

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456607

Properties cannot be async, so you need an async initialization that will set the property at its completion.

In your VM:

public BitmapImage Image { get; private set; }

public async Task Load()
{
  Image = await ConnectImage.GetImageAsync(...);
  ... // other asynchronously-loaded properties
}

And then have your page Loaded event load your VM:

public async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
  await vm.Load();
}

Your page will initially display with Image set to null, and when the image is loaded, it will show on the page.

Upvotes: 2

Related Questions