在WinRT应用程序中使用ISupportIncrementalLoading加载图像

时间:2015-11-07 16:42:08

标签: c# windows-runtime winrt-async winrt-httpclient

我正在开发一个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下载数据的方法的类。对于exapmle:

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,我有一个带MyObjectsCollection的ViewModel(当然它实现了ISupportIncrementalLoading),我在XAML中有一个标准的ListView,其中SourceItems绑定到MyObjectsCollection。一切正常,但只有在我没有照片下载MyObjects时。但是当我在foreach循环中使用LoadImage方法时,UI线程被锁定,几秒钟后出现新对象,用户无法滚动或按下按钮。我做错了什么?也许我应该以其他方式将Image分配给myObject.Image属性而不是Dispatcher?但是如果没有COMException,我怎么能这样做呢?谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我认为在这种情况下你可以将url绑定到图像的源,并使用DecodePixelHeight和DecodePixelWidth来优化性能

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding ImageUrl}"
                             DecodePixelHeight="200"
                             DecodePixelWidth="200"
                             DecodePixelType="Logical"/>
     </Image.Source>
</Image>