2014-11-24 95 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