在自定义ItemsPanel中实现UI虚拟化

我的目标是显示一些布局,如官方Android Imgur应用程序 ,其中项目具有固定宽度但可变高度。 我已经有一个带GridView的自定义面板。 有用。 然而,它打破了一些事情:

  1. 我没有获得UI虚拟化。 当需要渲染大量图像时,这是一个很大的性能瓶颈。
  2. 由于虚拟化已经消失,因此也不支持增量加载。

我搜索了很多,但我找不到任何关于如何实现虚拟化的文档。 所以,我有几个问题:

  1. 是否可以通过自定义面板实现虚拟化? 怎么样?
  2. 是否可以使用现有面板之一(例如VirtualizedStackPanel )来获得我需要的布局?

我不认为您可以在自定义面板上进行虚拟化。 我最后一次需要定制,虚拟化面板是你在Windows Photos应用程序中看到的原型,我从头开始完成所有虚拟化。 那么我会看到两个选项:

  1. 自己实现虚拟化 – 在ScrollViewer放置一个面板( Canvas可以很好地工作,但你也可以使用自定义面板),创建一些容器来填充几个屏幕的项目,并在滚动时重新排列容器及其内容以便始终具有实现窗口中的一些项目。 这很有趣,你可以获得惊人的性能,特别是如果你预先计算和缓存后台线程上的项目布局。 您可能需要付出一些努力来处理焦点,键盘输入(您应该始终保持聚焦容器无论窗口位置如何都可以实现)或可能的可访问性,但它是值得的。
  2. 在常规ListView使用自定义面板,但不是更改ListView.ItemsPanel – 将其保留为默认值( ItemsStackPanel )并将自定义布局面板放在项目模板中,并且这些面板具有高但不同的行。 这意味着您的布局不会在任何地方出现锯齿状 – 项目需要与某个地方的ListViewItems对齐,但实现基础知识要简单一些。 我认为照片应用程序中的布局是如何工作的。 您需要付出很多努力来覆盖ListView处理输入的方式并显示选择视觉效果,但它可能对您有用。 请记住,在这种情况下,您的ItemsSource将需要具有一组项目来在每个ListViewItem执行自定义布局。

我会选择第一个选项,但这取决于你。 最初这是一些更多的工作,但总的来说,最终可能更容易做到正确,让你自由地摆放没有任何行的东西,它会教你一些有用的东西。 第二个选项只是意味着你必须掩盖你不需要的内置行为。 我认为第一个选项还可以更好地将视图层与视图模型分开,因为ItemsSource不需要依赖于布局的分组,除非您实现某种视图层聚合器ItemsSource ,它将处理视图模型中的项目。

在这篇伟大的文章中阅读更多关于虚拟化的理论和实践:

ListView基础知识和虚拟化概念