在Windows上运行的ListView随机访问数据虚拟化 [英] Random access data virtualization for ListView on Windows Runtime

查看:143
本文介绍了在Windows上运行的ListView随机访问数据虚拟化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我采取列表,可以轻松拥有过万的小图片。实际使用的情况下呈现出的视频缩略图列表,以便您可以滚动经过一帧的视频帧。我把在视频的缩略图进入榜单第二的每2 /三度视频。我需要支持很长的视频(例如1小时的视频)。

I'm implementing a list that could easily have 10,000 small pictures in it. Actual use case is showing a list of thumbnails of a video so you can scroll thru a video frame by frame. I put in a thumbnail of the video into the list every 2/3rds of a second in the video. I need to support very long videos (e.g. 1hr video).

因此​​虚拟化选项:

<一个href=\"http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx\">http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx

我试过增量数据虚拟化,这对我来说会消耗太多的内存,因为图像只能通过数据流被称为,我想最终打开万流。这会崩溃一个Windows Phone应用程序由于内存不足。

I tried "Incremental data virtualization" and that consumes too much memory for me because the images can only be referred to via streams and I'd end up opening 10,000 streams. This would crash a windows phone application due to an out of memory.

现在我想试试随机访问数据虚拟化。我看到如何实现的接口 IObservableVector&LT;对象&gt ;, INotifyCollectionChanged (是&LT;对象&gt; B / C &LT; T&GT; 不工作)。最棘手的部分是我怎么能处理图像和负载图像。加载图像是一个异步方法。

Now I'd like to try "Random access data virtualization". I see how to implement the interfaces IObservableVector<object>, INotifyCollectionChanged (yes <object> b/c <T> doesn't work). The tricky part is how I can dispose of images and load images. Loading images is an Async method.

此外,我相信这个解决方案应该有占位符就像MSFT医生说这种类型的数据虚拟化的例子经常出现在图片浏览的应用程序,而是让用户等待下载所有的照片在相册中,应用程序示出的占位符的图像。由于每个图像被检索,该应用与实际照片的渲染替换该图像的占位符元素,即使所有的图像还没有被下载并显示时,用户仍然可以平移并与收集交互。

Additionally I believe this solution should have placeholders just as the MSFT doc says "An example of this type of data virtualization is often seen in photo viewing apps. Instead of making the user wait to download all photos in an album, the app shows placeholder images. As each image is retrieved, the app replaces the placeholder element for that image with a rendering of the actual photo. Even though all of the images have not been downloaded and displayed, the user can still pan and interact with the collection."

纵观MSFT样品的占位符 - 使用ContainerContentChanging似乎是一个重要途径。我在这里猜测,有一种方法来此事件处置中的形象,并开始图像的负载为好。
<一href=\"https://$c$c.msdn.microsoft.com/windowsapps/ListViewSimple-d5fc27dd\">https://$c$c.msdn.microsoft.com/windowsapps/ListViewSimple-d5fc27dd

Looking at the MSFT sample for placeholders - using "ContainerContentChanging" seems like an important path. I'm guessing here that there is a way to dispose of the image within this event, and start the load of an image as well. https://code.msdn.microsoft.com/windowsapps/ListViewSimple-d5fc27dd

沸腾下来的一个问题? - 在哪里可以处理的图像流,并为随机存取虚拟列表开始图像的加载这是照片的应用程序很常见的场景而且是超级容易在iOS中的事,但似乎没有人做过它的窗口运行呢。

Boiling this down to a question - Where is it possible to dispose of the image stream and start the load of an image for a random access virtualization list? This is a very common scenario in photo apps and is super easy to do in iOS, but seems no one has done it on windows runtime yet.

推荐答案

您必须适应VirtualizingCollection的实施,请检查下面的文章的 HTTP://www.$c$cproject.com/Articles/34405/WPF-Data-Virtualization

You must adapt the implementation of VirtualizingCollection, please check the following article http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization .

我写了使用VirtualizingCollection改编的样例应用程序的Windows Phone 8.1运行时应用。

I wrote an sample application using an adaptation of VirtualizingCollection for Windows Phone 8.1 Runtime App.

public class ThumbnailItem
{
    public Uri ImageUri { get; set; }
}

后来写ThumbnailItem人员。

Later write the ThumbnailItem provider.

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;
    }
}

然后,您的视图模型里面,你必须创建一个IList的财产和使用VirtualizingCollection的实现设置的值。我建议你​​使用AsyncVirtualizingCollection。

Then, inside your ViewModel, you must create a IList property and set the value using an implementation of VirtualizingCollection. I suggest you use AsyncVirtualizingCollection.

Items = new AsyncVirtualizingCollection<ThumbnailItem>(new ThumbnailProvider(1000000), 100);

最后,在视图中,必须使用您的视图模型的实例设置的DataContext对象和你的ListView应该类似于:

Finally, on the view you must set the DataContext object using an instance of your ViewModel and your ListView should look similar to:

<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>

当然,供应商的逻辑必须根据你的requierements改变,code我写的只是一个样本。

Of course, the logic of the provider must be changed according your requierements, the code I wrote is just a sample.

请,将其标记为答案,如果帮你。

Please, mark it as answer if helped you.

最好的问候,
丹尼斯

Best regards, Denys

修改
朋友@Quincy,我发布一个简单的例子,你能适应它。也许为你的应用ThumbnailItem类将包含FileName属性指示IsolateStorageFile文件名。在这种情况下,你必须创建转换器绑定,所以你需要实施的IValueConverter对象创建使用IsolateStorageFile一个BitmapImage的实例。

EDIT Friend @Quincy, I posted a simple example, you can adapt it. Maybe for your application the ThumbnailItem class will contain the Filename property indicating the IsolateStorageFile filename. In that case you must create a Binding with converter, so you needs to implement an IValueConverter object to create a BitmapImage instance using the IsolateStorageFile.

的BitmapImage形象=新的BitmapImage();
  image.SetSource(的资源文件);
  返回图像;

BitmapImage image = new BitmapImage(); image.SetSource(sourceFile); return image;

关于图像收盘,VirtualizingCollection已经默认定义的页面大小一100。你IsolateStorageFiles将可使用一次创造你的IValueConverter对象的BitmapImage。后来VirtualizingCollection将删除旧网页,如果他们不使用(没有显示,请检查VirtualizingCollection实现),最后是GC将关闭和放大器;处置的BitmapImage

About image closing, the VirtualizingCollection has defined a pagesize, 100 by default. Yours IsolateStorageFiles will be used one time to create the BitmapImage in your IValueConverter object. Later the VirtualizingCollection will delete old pages if they are not in use(not displayed, check VirtualizingCollection implementation), and finally the GC will close&dispose the BitmapImage.

移植VirtualizingCollection是容易的,我记得我只是做了AsyncVirtualizingCollection类的变化。我的解决方案很简单:

Porting VirtualizingCollection is easy, I remember I just did changes on AsyncVirtualizingCollection class. My solution was simple:

替换为ThreadPool.QueueUserWorkItem ThreadPool.RunAsync。

Replace ThreadPool.QueueUserWorkItem for ThreadPool.RunAsync.

替换为跟踪调试(只调试消息,并不重要)。

Replace Trace for Debug (just debug messages, not really important).

通过替换的SynchronizationContext方法的调用:

Replace SynchronizationContext methods invocation by using:

(用于Windows手机应用程序)CoreApplication.MainView.CoreWindow.Dispatcher。

(for windows phone app) CoreApplication.MainView.CoreWindow.Dispatcher.

(适用于Windows应用程序)CoreApplication.MainView.Dispatcher。

(for windows app) CoreApplication.MainView.Dispatcher.

我希望它可以帮助你。

这篇关于在Windows上运行的ListView随机访问数据虚拟化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆