2014-11-24 2 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(); 
    } 
} 

Основная проблема заключается в том, что я получаю изображение в байт [] (ByteArray) с сервера, и только выше код может отображать его на WP8.1. Поэтому я должен использовать метод dataWriter.StoreAsync(), но если я его использую, я должен использовать async, который должен быть недействительным. Но значение возврата void не подходит для меня из-за привязки.

Вы можете видеть исходный код, что я раскололся, но я не могу его использовать, потому что входное значение для image.SetSource() должно быть RandomAccessStream. Поэтому я не знаю, как я могу решить эту проблему.

+0

Вы только что загрузили файл изображения из Интернета? Или что байт поток что-то из webservice и своего рода уникальным? –

+0

Это аватар пользователя, с которым я могу связаться с этим URL-адресом: https://myapi.mywebpage.com/Image/[email protected] Итак, это происходит из веб-сервиса, и каждый элемент ListView содержит уникальную картинку , Загрузка изображений может занять больше времени, но я попытаюсь решить ее позже. – Speederer

+0

jpg? PNG? GIF? Base64 закодирован? Другие? –

ответ

3

Если вы хотите сделать привязку и использовать асинхронный метод, то один из способов сделать это работа, чтобы установить DataContext к Задача и связать его Результат. Степен Клири написал 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

+0

Привет, ты поможешь мне снова? :) Я хотел бы использовать эту функцию для отображения простого изображения. Поэтому он отлично работает, например, в ListView, но только когда я использую привязку. Я попытался установить ImageFromWeb с C#, но он там недоступен. У вас есть идеи? – Speederer

+0

И еще один вопрос: в методе GetImage() я хотел бы изменить System.Net.HttpClient на Windows.Web.Http.HttpClient. Но GetStreamAsync() отсутствует в нем. Есть ли другая функция вместо этого? – Speederer

Смежные вопросы