WP 8.1绑定来自http请求的图像

时间:2014-11-24 00:46:18

标签: image listview data-binding windows-phone-8.1 httpclient

我有一个ListView项目,其中包含来自http GET请求的数据和图像。我可以在ListView中显示所有数据,但图片除外。为了获取图像,我必须单独生成一个http GET请求。我可以使用以下代码显示图像:

private async void DisplayPicture()
{
    var ims = new InMemoryRandomAccessStream();
    var dataWriter = new DataWriter(ims);
    dataWriter.WriteBytes(App.answer.picture);
    await dataWriter.StoreAsync();
    ims.Seek(0);
    BitmapImage bitmap = new BitmapImage();
    bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
    bitmap.SetSource(ims);
}

但是如果我想在带有Binding的ListView中使用它,那么这不起作用。 这是我尝试的代码:

public class BinaryToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value != null && value is byte[])
        {
            var bytes = value as byte[];
            var ims = new InMemoryRandomAccessStream();
            var dataWriter = new DataWriter(ims);
            dataWriter.WriteBytes(bytes);
            //await dataWriter.StoreAsync();
            ims.Seek(0);
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(ims);
            //var ims = new MemoryStream(bytes);
            //var image = new BitmapImage();
            //image.SetSource(stream);
            //stream.Close();
            return bitmap;
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

主要问题是我从服务器获取byte [](bytearray)中的图像,只有上面的代码可以在WP8.1上显示它。所以我必须使用dataWriter.StoreAsync()方法,但如果我使用它,我必须使用async,它必须是无效的。但由于绑定,空值返回值对我不利。

您可以看到我取消注释的原始代码,但我无法使用它,因为image.SetSource()的输入值必须是RandomAccessStream。所以我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:4)

如果要进行绑定并使用异步方法,那么使其工作的一种方法是将 DataContext 设置为 Task 并绑定到其 Result < / em>的。 Stepen Cleary写了a nice article about that。您还可以在his answer here中找到一些有用的信息。

基于这个答案我已经建立了一个样本,我认为你可以修改它来满足你的需求。写一个 Converter ,它将返回 TaskCompletionNotifier (参见Stephen上面的回答):

public class WebPathToImage : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null) return null;
        // the below class you will find in Stephen's answer mentioned above
        return new TaskCompletionNotifier<BitmapImage>(GetImage((String)value));
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    { throw new NotImplementedException(); }

    private async Task<BitmapImage> GetImage(string path)
    {
        HttpClient webCLient = new HttpClient();
        var responseStream = await webCLient.GetStreamAsync(path);
        var memoryStream = new MemoryStream();
        await responseStream.CopyToAsync(memoryStream);
        memoryStream.Position = 0;
        var bitmap = new BitmapImage();
        await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
        return bitmap;
    }
}

然后你可以在XAML中定义绑定:

<Image DataContext="{Binding ImageFromWeb, Converter={StaticResource WebPathToImage}}" Stretch="Uniform" 
       Source="{Binding Result}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="2"/>

设置ImageFromWeb时,一切都应该有效:

ImageFromWeb = @"http://www.onereason.org/wp-content/uploads/2012/02/universe-300x198.jpg";