在 WinRT 应用程序中使用 ISupportIncrementalLoading 加载图像
Loading images with ISupportIncrementalLoading in WinRT app
我正在开发 Windows Phone 8.1 应用程序,我想使用 ISupportIncrementalLoading 接口从 REST API 服务器加载对象列表。关注这篇文章 https://marcominerva.wordpress.com/2013/05/22/implementing-the-isupportincrementalloading-interface-in-a-window-store-app/ 我创建了一些 classes 以这种方式下载我的对象:
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);
}
}
}
我的来源class增量加载数据:
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 是一个 class,具有通过 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,我有一个带有 MyObjectsCollection 的 ViewModel(当然它实现了 ISupportIncrementalLoading),我在 XAML 中有一个标准的 ListView,SourceItems 绑定到 MyObjectsCollection .一切正常,但只有在我下载没有照片的 MyObjects 时才有效。但是当我在 foreach 循环中使用 LoadImage 方法时 UI 线程被锁定并且新对象在几秒钟后出现并且用户无法滚动或按下按钮。我做错了什么?也许我应该以其他方式而不是 Dispatcher 将图像分配给 myObject.Image 属性?但是如果没有 COMException 我怎么能这样做呢?感谢您的帮助。
我认为在这种情况下,您可以将 url 绑定到图像源,并使用 DecodePixelHeight 和 DecodePixelWidth 来优化性能
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding ImageUrl}"
DecodePixelHeight="200"
DecodePixelWidth="200"
DecodePixelType="Logical"/>
</Image.Source>
</Image>
我正在开发 Windows Phone 8.1 应用程序,我想使用 ISupportIncrementalLoading 接口从 REST API 服务器加载对象列表。关注这篇文章 https://marcominerva.wordpress.com/2013/05/22/implementing-the-isupportincrementalloading-interface-in-a-window-store-app/ 我创建了一些 classes 以这种方式下载我的对象:
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);
}
}
}
我的来源class增量加载数据:
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 是一个 class,具有通过 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,我有一个带有 MyObjectsCollection 的 ViewModel(当然它实现了 ISupportIncrementalLoading),我在 XAML 中有一个标准的 ListView,SourceItems 绑定到 MyObjectsCollection .一切正常,但只有在我下载没有照片的 MyObjects 时才有效。但是当我在 foreach 循环中使用 LoadImage 方法时 UI 线程被锁定并且新对象在几秒钟后出现并且用户无法滚动或按下按钮。我做错了什么?也许我应该以其他方式而不是 Dispatcher 将图像分配给 myObject.Image 属性?但是如果没有 COMException 我怎么能这样做呢?感谢您的帮助。
我认为在这种情况下,您可以将 url 绑定到图像源,并使用 DecodePixelHeight 和 DecodePixelWidth 来优化性能
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding ImageUrl}"
DecodePixelHeight="200"
DecodePixelWidth="200"
DecodePixelType="Logical"/>
</Image.Source>
</Image>