【问题标题】:ListBox not Virtualizing列表框未虚拟化
【发布时间】:2012-09-16 04:14:48
【问题描述】:

我有一个未虚拟化的 ListBox。我显然错过了一些东西,但找不到它。

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

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

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

我错过了什么?

【问题讨论】:

    标签: wpf mvvm binding blend


    【解决方案1】:

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

    stackpanel 的内容永远不会在其堆叠方向上对齐拉伸,因此您的列表框将始终拥有它要求的所有空间,然后您就无法获得虚拟化。你的内部列表框也不会得到任何垂直滚动条。

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

    1:在您的内部列表框上设置 maxheight - 可能是最简单的。

    希望对你有帮助:)

    【讨论】:

    • 谢谢符文。 StackPanel 提供所有需要的空间是有意义的。我将考虑更改 ControlTemplate。如果这不起作用,我会考虑使用 TreeView。
    • 我查看了 Expanders 模板,但没有 StackPanel。只是标题的 ToggleButton 和内容的 ContentPresenter。我搬到树上,发现限制。没有多选和虚拟化似乎只适用于根项目。啊。经过更多研究后,我将在 TreeView 上发布另一个问题。
    • 啊,是的 - 我有点偏离,它派生自 HeaderedContentControl,但有一个 ControlTemplate,它实际上是一个停靠面板。所以排除了解决方案2。再次查看您的描述时,您的子列表框位于一个列表框中,该列表框有一个用于其项目的堆栈面板。所以你的外部列表框虚拟化?我认为您必须在内部列表框上设置 MaxHeight 才能使它们虚拟化。关于 TreeView - 据我所知,treeview 根本没有虚拟化。
    猜你喜欢
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 2012-12-26
    • 2020-10-03
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多