2014-11-24 81 views
2

我有一个ListView项目,其中包含来自http GET请求的数据和图像。除了图片外,我可以在ListView中显示所有数据。为了获得图像,我必须做一个单独的http GET请求。我可以用此代码显示图像:WP 8.1从http请求绑定图像

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 [](字节阵列)的图像,只有上面的代码可以在WP8.1显示。所以我必须使用dataWriter.StoreAsync()方法,但如果我使用它,我必须使用async,它必须是无效的。但由于绑定,无效返回值对我来说并不好。

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

+0

你只是从网上下载图像文件?或者是来自web服务的字节流,有点独特? – 2014-11-24 02:15:50

+0

这是一个用户头像,我可以通过以下URL访问:https://myapi.mywebpage.com/Image/[email protected]所以它来自web服务,每个ListView项目都包含一个独特的图片。下载图片可能需要较长时间,但我会尽力在稍后解决。 – Speederer 2014-11-24 07:18:53

+0

jpg? PNG? GIF? Base64编码?其他? – 2014-11-24 07:41:20

回答

3

如果你想结合使用异步方法,那么一个方法,使其工作是的DataContext设置为任务并绑定到其结果。 Stepen Cleary写道:a nice article about that。您还可以在his answer here中找到一些有用的信息。

基于这个答案,我建立了一个样本,我认为你可以修改以满足你的需求。写转换将返回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"; 
+0

谢谢,它完美的作品! :) – Speederer 2014-11-24 20:51:59

+0

嗨,你能再次帮助我吗? :)我想用这个功能来显示一个简单的图片。所以它在例如ListView中工作得很好,但只有当我使用绑定。我试图从c#设置ImageFromWeb,但它不可用。你有什么想法吗? – Speederer 2014-12-09 23:27:45

+0

还有一个问题:在GetImage()方法中,我想将System.Net.HttpClient更改为Windows.Web.Http.HttpClient。但是GetStreamAsync()从它缺失。有没有其他的功能,而不是这个? – Speederer 2014-12-09 23:32:45