c# – Windows运行时ListView的随机访问数据虚拟化

前端之家收集整理的这篇文章主要介绍了c# – Windows运行时ListView的随机访问数据虚拟化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在实施一个可以轻松拥有10,000张小图片的列表.实际用例显示视频的缩略图列表,以便您可以一帧一帧地滚动视频.我将视频的缩略图放在视频中的每隔2/3的列表中.我需要支持很长的视频(例如1小时视频).

所以虚拟化选项:

http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx

我尝试了“增量数据虚拟化”,对我来说消耗了太多的内存,因为图像只能通过流引用,我最终会打开10,000个流.由于内存不足,这将导致Windows Phone应用程序崩溃.

现在我想尝试“随机访问数据虚拟化”.我看到如何实现接口IObservableVector< object&gt ;,INotifyCollectionChanged(yes< object> b / c< T>不起作用).棘手的部分是我如何处理图像和加载图像.加载图像是一种Async方法.

此外,我认为这个解决方案应该具有占位符,就像MSFT文档所说“这种类型的数据虚拟化的一个例子经常在照片查看应用程序中看到,而不是让用户等待下载专辑中的所有照片,应用程序会显示占位符图像当每个图像被检索时,应用程序用实际照片的渲染替代该图像的占位符元素,即使所有的图像都没有被下载和显示,用户仍然可以平移和与集合进行交互.

查看占位符的MSFT示例 – 使用“ContainerContentChanging”似乎是一个重要的路径.我在这里猜测,在这个事件中有一种处理图像的方法,并开始加载图像.
@L_502_1@

将这个问题解决一个问题 – 哪里可以处理图像流并开始为随机访问虚拟化列表加载图像?这是照片应用程序中非常常见的情况,并且在iOS中非常简单,但似乎没有人在Windows运行时执行此操作.

解决方法

您必须调整VirtualizingCollection的实现,请检查以下文章 http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization.

我使用适用于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.

我希望它能帮助你.

猜你在找的C#相关文章