2012-09-24 130 views
1

我有一个不虚拟化的ListBox。我明显错过了一些东西,但找不到它。列表框不虚拟化

它实际上是一个ListBox内的列表框。外部ListBox有一个包含Expander的ItemTemplate。扩展器用于显示一组项目。 Expander的内容是显示项目的第二个ListBox。第二个ListBox上的ItemTemplate绑定到要显示的实际Item。我的项目的ViewModel类具有许多属性,这些属性在调用Get属性之前不会初始化数据。但是,WPF遍历每个项目并导致初始化逻辑,我试图避免。

我发现使用ListCollectionView.GroupDescription会导致ListBox不能虚拟化。现在我正在ViewModel中处理自己的分组。我的外部ListBox绑定到一个ObservableCollection(ItemGroupViewModel),其中ItemGroupViewModel有一个GroupName和一个Items列表。第二个ListBox绑定到ItemGroupViewModel中的Items。这并没有解决问题。我也在调试时检查了VirtualizingStackPanel.GetIsVirtualizing(),它返回true,但WPF仍然遍历每一个项目。我已经进行了两次检查,以确保我的分组逻辑不会触发每个项目中的数据初始化逻辑,这是我试图避免的。

我认为IsSharedSizeScope可能会导致ListBox渲染所有项目以确定列大小。所以我关闭了SharedSizeScope。仍然没有虚拟化。

我错过了什么?

回答

2

它不是虚拟化的,因为它在扩展器内部,扩展器的模板是headeredcontentcontrol(据我所知),它的模板包含一个stackpanel。

堆栈面板的内容永远不会沿堆栈方向拉伸,因此您的列表框将始终具有它请求的所有空间,然后就不会获得虚拟化。你的内部列表框也不会得到任何垂直滚动条。

你有一个解决方案(至少:)

1:maxheight设置你的内心列表框 - 可能是最容易。

希望它有帮助:)

+0

感谢符文。提供所有需要的空间的StackPanel是合理的。我会研究改变ControlTemplate。如果这不起作用,我会考虑使用TreeView。 – Jayson

+0

我看着扩展模板,并没有StackPanel。只需一个用于标题的ToggleButton和用于内容的ContentPresenter。我搬到了树上,发现了一些限制。没有多重选择和虚拟化似乎只对根项目起作用。啊。经过一些更多的研究后,我会在TreeView上发布另一个问题。 – Jayson

+0

啊是的 - 我有点偏离它,它来自HeaderedContentControl,但有一个ControlTemplate实际上是一个dockpanel。所以解决方案2被排除了。当再次查看你的描述时,你将你的子列表框放在一个列表框中,该列表框中有一个用于其项目的堆栈面板。所以你的外部列表框虚拟化?我认为你必须在你的内部列表框中设置MaxHeight来让它们虚拟化。关于TreeView - 据我所知,treeview根本没有虚拟化。 –