Загрузка изображений с помощью ISupportIncrementalLoading в приложении WinRT

Я занимаюсь разработкой приложения для Windows Phone 8.1 и хотел бы использовать интерфейс ISupportIncrementalLoading для загрузки списка объектов с сервера REST API. Следуйте этой статье https://marcominerva.wordpress.com/2013/05/22/implementing-the-isupportincrementalloading-interface-in-a-window-store-app/ Я создал несколько классов, где я загружаю свои объекты в этом путь:

public class MyObject
{
   private ImageSource image;

   public int Id { get; set; }
   public string Desription { get; set; }
   public string PhotoLink { get; set; }
   public ImageSource Image
   {
       get
       {
           return this.image;
       }

       set
       {
           this.image = value;
           this.RaisePropertyChanged(() => this.Image);
       }
   }
}

И мой исходный класс для инкрементальной загрузки данных:

public async Task<IEnumerable<MyObject>> GetPagedItems(int pageIndex, int pageSize)
{
    var myObjects = await this.httpService.GetObjects(pageSize);
    if(myObjects != null)
    {
        foreach (var myObject in myObject)
        {       
            this.LoadImage(myObject);
        }
    }
    return myObjects;
}

private async void LoadImage(MyPbject myObject)
{
    if (myObject.PhotoLink != null)
    {
        var imageSource = await this.httpService.GetImage(myObject.PhotoLink);

        DispatcherHelper.CheckBeginInvokeOnUI(() =>
        {
            myObject.Image = imageSource;
        });
    }
}

Закрытый объект httpService - это класс с методами для загрузки данных через HttpClient. Например:

private async Task<ImageSource> GetImage(string imageUrl)
{
    using (HttpClient httpClient = new HttpClient())
    {
        using (Stream stream = await httpClient.GetStreamAsync(imageUrl))
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                await stream.CopyToAsync(memoryStream);
                memoryStream.Position = 0;
                var bitmap = new BitmapImage();
                bitmap.SetSource(memoryStream.AsRandomAccessStream());
                return bitmap;
            }
        }
    }
}

Я использую MVVMLight в своем проекте, и у меня есть ViewModel с MyObjectsCollection (который, конечно, реализует ISupportIncrementalLoading), и у меня есть стандартный ListView в XAML с SourceItems, привязанным к MyObjectsCollection. Все работает нормально, но только когда я загружаю MyObjects без фотографий. Но когда я использую метод LoadImage в цикле foreach, поток пользовательского интерфейса блокируется, и через несколько секунд появляются новые объекты, и пользователь не может прокручивать или нажимать кнопки. Что я делаю не так? Может быть, я должен назначить Image свойству myObject.Image другим способом, а не Dispatcher? Но как я могу сделать это без COMException? Спасибо за любую помощь.

1 ответ

Решение

Я думаю, что в этом случае вы можете привязать URL к источнику изображения и использовать DecodePixelHeight и DecodePixelWidth для оптимизации производительности

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding ImageUrl}"
                             DecodePixelHeight="200"
                             DecodePixelWidth="200"
                             DecodePixelType="Logical"/>
     </Image.Source>
</Image>
Другие вопросы по тегам