【问题标题】:WP 8.1 Binding image from a http requestWP 8.1 来自 http 请求的绑定图像
【发布时间】:2014-11-24 17:57:20
【问题描述】:

我有一个 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);
}

但是,如果我想在带有绑定的 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,它必须是无效的。但是由于绑定,void返回值对我不利。

你可以看到我未注释的原始代码,但我不能使用它,因为image.SetSource() 的输入值必须是随机访问流。所以我不知道如何解决这个问题。

【问题讨论】:

  • 您只是从网上下载图像文件吗?或者那个字节流来自网络服务并且有点独特?
  • 这是一个用户头像,我可以通过这个网址访问:myapi.mywebpage.com/Image/Downloadavatar?Email=user@example.com 所以它来自一个网络服务,每个 ListView 项目都包含一张独特的图片。图片下载可能需要较长时间,但我稍后会尝试解决。
  • jpg? ? gif? Base64 编码?其他的?

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


【解决方案1】:

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

基于该答案,我构建了一个示例,我认为您可以对其进行修改以满足您的需求。编写一个 Converter ,它将返回 TaskCompletionNotifier(参见上面斯蒂芬的回答):

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";

【讨论】:

  • 嗨,你能再帮我一次吗? :) 我想用这个功能来显示一张简单的图片。因此,例如在 ListView 中它工作得很好,但仅在我使用绑定时。我试图从 c# 设置 ImageFromWeb,但它在那里不可用。你有什么想法吗?
  • 还有一个问题:在 GetImage() 方法中,我想将 System.Net.HttpClient 更改为 Windows.Web.Http.HttpClient。但是其中缺少 GetStreamAsync()。有没有其他功能代替这个?
  • @Speederer 如果您不需要绑定,则 BitmapImage 具有例如 SetSourceAsync 方法。至于 HttpClient,有 GerAsync 方法,然后你会得到一个带有 ContentHttpResponseMessage。另外请不要在 cmets 中提出新问题 - 这不是他们的目的。
  • 好的,谢谢!我会试试的。我不会再在 cmets 中问了。
  • 它在 2019 年仍然有效,最新版本的 UWP (1809)。很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2018-04-05
  • 2015-05-13
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多