【发布时间】:2014-09-11 10:14:54
【问题描述】:
WPF 和 WinRT (C# + XAML) 都使用支持 UI 虚拟化的面板(例如 VirtualizingStackPanel 等)来支持 UI 虚拟化。使用 MVVM 时,它是使用某种ItemsControl 来完成的(ListBox、GridView 等...),它绑定到视图模型上的可枚举属性(通常是 ObservableCollection)。 items 控件仅为可见的项目创建 UI。之所以称为 UI 虚拟化,是因为只有 UI 是虚拟化的。只有未呈现的项目的视图不会被创建,并且会延迟到用户实际滚动到项目的那一刻。列表中的视图模型对象都是预先创建的。因此,如果我有一个 100,000 人的列表要呈现,ObservableCollection 将必须包含 100,000 个视图模型,无论用户何时将它们滚动到视图中。
在我们的应用程序中,我们希望实现它,以便视图模型层成为这种虚拟化的一部分。我们希望 items 控件呈现一个适合可能加载的项目总数的滚动条(因此 observable 集合应该使 items 控件认为它已经包含 100,000 个项目,因此滚动条视图端口位于合适的大小),但我们希望在新项目即将进入视野时通知可观察集合,以便它可以从服务器加载实际对象。我们希望能够在加载的项目中显示某种进度指示器,然后在项目加载到可观察集合后立即将其替换为项目的实际数据模板。
我们希望尽可能地保持 MVVM 准则,但性能和响应能力是重中之重。如果可能,我们也更喜欢可重复使用的解决方案。
解决这个问题的最佳方法是什么?
【问题讨论】:
-
这个问题太宽泛了,无法回答。当然,您已经对应该做什么有了一些想法。请把它分解成可以回答的小问题。
-
我不明白为什么它太宽泛了......我描述了一个非常具体的场景,我想知道是否已经有最佳实践。肯定有人以前尝试过。
-
您想要:a) 能够虚拟化其数据的集合,b) 知道如何处理虚拟化数据源的自定义 ItemsControl,c) ItemsControl 和集合之间的通知机制 d) a表示 ItemsControl 中的项目的自定义控件,它知道它是否已加载,并且 e) (a)、(b)、(c) 和 (d) 应该是高性能的。除了听起来很宽泛(至少对我来说,YMMV),我几乎可以保证没有“最好的方法”来解决它。
-
我想在视图模型层允许虚拟化。那是一个)。我认为不需要特殊的项目控件,或者超出正常属性更改和集合更改机制的通知机制。我认为不需要自定义控件,因为数据模板可以实现我编写的所有内容。但是,如果有一个解决方案确实涉及您所写的所有内容,那么它也会被接受。是的,性能是一个因素。我不是要一个完整的解决方案的源代码,只是关于如何开始解决这个问题的指南。为什么这么困扰你?
-
它并没有特别困扰我。我只是认为这个问题太宽泛了,因此给了它一个近距离的投票。其他人可能会也可能不会效仿(需要 5 票接近才能结束问题)。这不是为了惹恼你;这样做是为了保持问题的质量水平,并且至少是为了向发布者发出一个信号,即可能需要改进或附加细节才能回答问题,我认为这也是你的目的。
标签: c# xaml mvvm winrt-xaml ui-virtualization