所以虚拟化选项:
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx
我尝试了“增量数据虚拟化”,对我来说消耗了太多的内存,因为图像只能通过流引用,我最终会打开10,000个流.由于内存不足,这将导致Windows Phone应用程序崩溃.
现在我想尝试“随机访问数据虚拟化”.我看到如何实现接口IObservableVector< object> ;,INotifyCollectionChanged(yes< object> b / c< T>不起作用).棘手的部分是我如何处理图像和加载图像.加载图像是一种Async方法.
此外,我认为这个解决方案应该具有占位符,就像MSFT文档所说“这种类型的数据虚拟化的一个例子经常在照片查看应用程序中看到,而不是让用户等待下载专辑中的所有照片,应用程序会显示占位符图像当每个图像被检索时,应用程序用实际照片的渲染替代该图像的占位符元素,即使所有的图像都没有被下载和显示,用户仍然可以平移和与集合进行交互.
查看占位符的MSFT示例 – 使用“ContainerContentChanging”似乎是一个重要的路径.我在这里猜测,在这个事件中有一种处理图像的方法,并开始加载图像.
https://code.msdn.microsoft.com/windowsapps/ListViewSimple-d5fc27dd
将这个问题解决一个问题 – 哪里可以处理图像流并开始为随机访问虚拟化列表加载图像?这是照片应用程序中非常常见的情况,并且在iOS中非常简单,但似乎没有人在Windows运行时执行此操作.
解决方法
我使用适用于Windows Phone 8.1运行时应用程序的VirtualizingCollection编写了一个示例应用程序.
public class ThumbnailItem { public Uri ImageUri { get; set; } }
稍后写入ThumbnailItem提供程序.
public class ThumbnailProvider : IItemsProvider<ThumbnailItem> { private readonly int _itemsCount; public ThumbnailProvider(int itemsCount) { _itemsCount = itemsCount; } public int FetchCount() { return _itemsCount; } public IList<ThumbnailItem> FetchRange(int startIndex,int count) { var items = new List<ThumbnailItem>(); while (count-- > 0) { items.Add(new ThumbnailItem() { ImageUri = new Uri("ms-appx:///Assets/Square71x71logo.scale-240.png") }); } return items; } }
然后,在您的viewmodel中,您必须创建一个IList属性并使用VirtualizingCollection的实现设置该值.我建议你使用AsyncVirtualizingCollection.
Items = new AsyncVirtualizingCollection<ThumbnailItem>(new ThumbnailProvider(1000000),100);
最后,在视图中,您必须使用viewmodel的实例设置DataContext对象,并且您的ListView应该类似于:
<ListView ItemsSource="{Binding Items,Mode=OneWay}" VirtualizingStackPanel.VirtualizationMode="Recycling"> <ListView.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Orientation="Horizontal"/> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListView.ItemTemplate> <DataTemplate> <Grid Margin="0 0 20 20"> <Image Source="{Binding ImageUri,Mode=OneTime}" Width="72" Height="72"/> </Grid> </DataTemplate> </ListView.ItemTemplate>
当然,提供者的逻辑必须根据您的要求进行更改,我写的代码只是一个示例.
请帮助你,把它标记为答案.
最好的祝福,
丹尼斯
编辑
朋友@Quincy,我发了一个简单的例子,你可以适应它.也许对于您的应用程序,ThumbnailItem类将包含指定IsolateStorageFile文件名的Filename属性.在这种情况下,您必须创建一个带转换器的绑定,因此您需要实现一个IValueConverter对象,以使用IsolateStorageFile创建一个BitmapImage实例.
BitmapImage image = new BitmapImage();
image.SetSource(sourceFile);
return image;
关于图像关闭,VirtualizingCollection已经定义了一个pagesize,默认情况下是100.您的IsolateStorageFiles将被用于在您的IValueConverter对象中创建BitmapImage.以后,如果VirtualizingCollection没有被使用(未显示,检查VirtualizingCollection实现),那么VirtualizingCollection将会删除旧页面,最后GC将关闭并处理BitmapImage.
移植VirtualizingCollection很简单,我记得我刚刚在AsyncVirtualizingCollection类上做了更改.我的解决方案很简单:
为ThreadPool.RunAsync替换ThreadPool.QueueUserWorkItem.
替换跟踪调试(只是调试消息,不是很重要).
通过使用以下命令替换SynchronizationContext方法调用:
(Windows Phone应用程序)CoreApplication.MainView.CoreWindow.Dispatcher.
(Windows应用程序)CoreApplication.MainView.Dispatcher.
我希望它能帮助你.