标签: data-virtualization

DataGrid行请求模式与数据虚拟化

我使用CodePlex的一些想法和Bea Stollnitz的博客以及Vincent Da Ven Berhge的论文(同一链接)实现了数据虚拟化解决方案.但是我需要一种不同的方法,所以我决定编写自己的解决方案.

DataGrid用这个解决方案来显示大约一百万行.我也在使用UI虚拟化.我的解决方案是可行的,但我在某些情况下遇到了一些奇怪的行为,这些行为是关于如何DataGrid从源头请求数据的.

关于解决方案

我最终编写了一份列表来完成所有繁重的工作.它是一个名为VirtualList<T>.It 的泛型类,它实现了ICollectionViewFactory接口,因此集合视图创建机制可以创建一个VirtualListCollectionView<T>实例来包装它.这个类继承自ListCollectionView.我没有按照建议编写我自己的ICollectionView实现.继承似乎也很好.

VirtualList<T>分裂整个数据到页.它获取总项数,每次DataGrid通过列表索引器对行进行请求时,它会加载相应的页面或从缓存中返回.页面在内部回收,并DispatcherTimer在空闲时间处理未使用的页面.

数据请求模式

  • 我学到的第一件事就是VirtualList<T>实现IList(非泛型).否则,ItemsControl它将把它视为一个IEnumerable并查询/枚举所有行.这是合乎逻辑的,因为DataGrid它不是类型安全的,所以它不能使用IList<T>接口.

  • 带有0索引的行经常被问到DataGrid.它似乎用于视觉项目测量(根据调用堆栈).所以,我只是缓存这一个.

  • 内部的缓存机制DataGrid使用可预测的模式来查询它显示的行.首先它要求从上到下的可见行(每行两次),然后它在可见区域(包括第一个可见行)之前查询几行(取决于可见区域的大小)从下到上依次订购.之后,它在从上到下的可见行(包括最后一个可见行)之后请求相同数量的行.

    如果可见行索引是4,5,6.数据请求将是:4,4,5,5,6,6,4,3,2,1,6,7,8,9.

    如果我的页面大小设置正确,我可以从当前和以前加载的页面提供所有这些请求.

  • 如果CanSelectMultipleItemsTrue并且用户使用SHIFT按钮或鼠标拖动选择多个项目,则DataGrid枚举从列表开头到选择结尾的所有行.IEnumerable无论IList是否实现,此枚举都通过接口发生.

  • 如果所选行不可见且当前可见区域与所选行"远",则有时DataGrid会开始请求从所选行到可见区域末尾的所有项目.包括其间甚至不可见的所有行.我无法弄清楚这种行为的确切模式.也许我的实施就是这个原因.

我的问题

  • 我想知道,为什么DataGrid不可见行的请求,因为这些行将在可见时再次请求?

  • 为什么有必要要求每一行两到三次?

  • 任何人都可以告诉我如何使DataGrid不使用IEnumerable,除了关闭多个项目选择?

wpf datagrid data-virtualization

11
推荐指数
1
解决办法
1561
查看次数

C#中的WinRT数据虚拟化实现

在MSDN论坛上问了这个问题(没有成功),也许StackOverflow会再次证明它的实力......

我参加了Hamid Mahmood关于收集和列表应用程序的会议,并很高兴看到数据虚拟化的控制级支持.遗憾的是,没有详细说明如何实现IVirtualizingVectorIIncrementalLoadingVector,并且通过查看接口本身并不明白如何做到这一点.有人可以寄样品吗?

针对SO的额外奖励问题 - 是否有一种更简单的方法来实现IAsyncOperation(IIncrementalLoadingVector实现所需)而不是"从头开始"编码?

c# data-virtualization windows-8 windows-runtime

7
推荐指数
1
解决办法
1841
查看次数

在wpf中重复打开对话框时的性能问题

我有一个启动对话框按钮,它创建一个窗口的视图模型并将其绑定到窗口(它启用了UI虚拟化).第一次单击启动对话框只需1秒钟.但是如果我经常或背靠背打开相同的对话框,它会花费更多的时间来填充网格数据源以进行下一次迭代.如果我暂停一下,然后再打开窗口,那么只需要大约1或2秒钟.

for first time populating the item source it take only 1 second:
next time populating the item source it takes  2 second
next time populating the item source it takes  3 second
next time populating the item source it takes  6 second
next time populating the item source it takes  8 second
Run Code Online (Sandbox Code Playgroud)

但是,如果我调用不推荐的GC.Collect(),那么填充网格数据源总是需要大约1秒钟.但呼唤

Gc.Collect()
Gc.WaitForPendingFinalizer()
Gc.Collect()
Run Code Online (Sandbox Code Playgroud)

每次迭代花费我一些时间.

我知道打电话GC.Collect不是一个好选择.任何人都可以建议我如何提高我的应用程序性能.

我更关心用户机器,因为我的机器具有非常好的配置,而用户机器可能不那么快.

c# wpf garbage-collection data-virtualization

7
推荐指数
1
解决办法
309
查看次数

如何在不使用分页的情况下实现延迟加载的Silverlight数据网格

使用全新发布的RIA服务中的业务应用程序模板,您可以看到许多示例使用数据网格DomainDataSource与a结合使用DataPager.属性PageSize和LoadSize可用于调整要在一个页面中显示的数据量以及在后台预取的数据.

现在我想要一个带滚动条但没有寻呼机的数据网格.底层DomainDataSource应该只加载在网格中显示的数据.当用户向下滚动到尚未在数据上下文中的项时,它应该触发另一个加载.是否有任何示例实现如何执行此操作?

silverlight silverlight-4.0 wcf-ria-services data-virtualization

6
推荐指数
1
解决办法
3191
查看次数

当使用数据虚拟化进行多重选择时,DataGrid会请求

添加4个月前的帖子,遗憾的是没有得到任何答案.

在带有shift的数据网格中使用多选时,我基本上站在同一个问题之前.

当在一个巨大的列表中间的某个地方(说它是网格中的1,000,000个项目,所有数据都已虚拟化)而我使用shift +鼠标点击从500,000到500,050中选择,网格调用我的"GetEnumerator()"方法虚拟列表(类似于Vincent和Paul的实现).到目前为止我所做的只是缓存页面上的SelectMany.但不幸的是导致行没有被正确选择(当ctrl +鼠标点击完成工作!).

所以我发现,DataGrid实际上期望从索引0到最后一个选择的所有项目.显然,这对于1m项目的列表并不理想,因为这将导致从0到(在我的示例中)500,050中的每个项目的请求,从而将所有内容加载到数据库中.

所以我的问题与丹尼尔在上面发布的那些问题相同:

  • 为什么DataGrid多次请求项目(连续6-7次请求所选项目,没有明显原因)?

  • 有没有办法告诉DataGrid不要使用枚举器,只是选择项目而不是从0开始迭代?

非常感谢,希望我能更好地获得至少引人深思的答案,因为没有太多关于数据虚拟化的信息.

wpf datagrid data-virtualization

6
推荐指数
1
解决办法
1241
查看次数

Wpf TreeView具有列,具有UI虚拟化和DataVirtualization

我正在寻找一个wpf控件(免费或商业).树应支持所有常规树视图特性(样式,数据模板,控件模板......),并支持使用Columns布局(类似于Visual Studio中的Watch窗口).

但是也:

  1. 良好的虚拟化 - 应该支持数千个元素
  2. 内置数据虚拟化 - 数据的加载和处理速度很慢,无法一次性完成并按特定顺序完成(类似于分页)
  3. 查看模型支持和绑定,我更喜欢使用视图模型的类型来调查树,而不是调查树本身
  4. 内置支持对数据表示进行搜索和过滤,然后在树上的可视元素上反映匹配
  5. 准确,快速滚动和移动到特定元素的选项(我更喜欢,使用项目的ViewModel表示).

不想自己构建树,我正在寻找现有的实现,至少支持虚拟化和数据虚拟化.

c# wpf treeview wpf-controls data-virtualization

5
推荐指数
1
解决办法
682
查看次数

绑定到 WPF DataGrid 时使用数据虚拟化并支持排序

我正在将一个大型集合(250,000 多条记录)绑定到 DataGrid。为此,它必须同时使用 UI 虚拟化和数据虚拟化。经过一番研究,我想出了如何让这两种虚拟化工作。但是,一旦我通过单击 DataGrid 中的列标题进行排序,它就会放弃数据虚拟化并尝试将整个数据集读入内存。

相反,我希望它将排序命令传递给底层集合,以便数据库在从磁盘检索数据之前执行排序。有没有办法做到这一点?

c# wpf datagrid data-virtualization

5
推荐指数
1
解决办法
1073
查看次数

MVVM 与数据虚拟化

我有一个绑定到 ViewModel 实例树的 TreeView。问题是模型数据来自一个缓慢的存储库,所以我需要数据虚拟化。节点下的子ViewModel列表只有在父树视图节点展开时才加载,折叠时卸载。

如何在遵守 MVVM 原则的同时实现这一点?ViewModel 如何获得需要加载或卸载子节点的通知?那是当一个节点在不知道树视图存在的情况下展开或折叠时?

有些事情让我觉得数据虚拟化不适合 MVVM。由于在数据虚拟化中,ViewModel 通常需要非常了解 UI 的当前状态,并且还需要控制 UI 中的许多方面。再举一个例子:

具有数据虚拟化的列表视图。ViewModel 需要控制 ListView 滚动拇指的长度,因为它取决于模型中的项目数。此外,当用户滚动时,ViewModel 需要知道他滚动到哪个位置以及列表视图有多大(当前适合多少项目)才能从存储库加载模型数据的正确部分。

wpf mvvm data-virtualization

4
推荐指数
1
解决办法
2671
查看次数