将嵌套容器(virtualizingstackpanel)虚拟化为WPF中的单个父滚动条

时间:2009-07-30 15:38:49

标签: wpf virtualization virtualizingstackpanel

我有点把自己编成了这个腌菜。我正在编写一个自定义WPF控件,它类似于This MSDN article中描述的TreeListView以及网上的许多其他位置。在这一点上,相当大的一件事是定制的,除了在虚拟化方面,它还能很好地实现我的目标。我的覆盖TreeViewTreeViewItem模板都使用VirtualizingStackPanel来展示他们的项目,并且我已经验证所有这些都是按预期创建的。虚拟化在根级别项目上正常工作(只有ScrollViewer中当前可见的UI元素已经生成),TreeView内容负责不生成折叠节点的元素。扩展节点时会出现问题 - 所有元素都为节点中的每个子节点制作,甚至是屏幕外的数千个节点。

在我看来,我需要做的就是以某种方式将内部嵌套VirtualizingStackPanel的scrollowner属性设置为默认情况下根级别VSP连接到的相同主滚动视图,但我读了一个MSFT海报here说这不起作用。

不幸的是,这个东西很慢,因为没有虚拟化的泥浆,所以我需要提出某种解决方案。任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但对我来说仍然很重要。

在我的情况下,我认为TreeView不会剪切它,因为我只需要两层,所显示的项目类型在两层之间是不同的。另外,我正在重构一个Expander的列表,所以我在考虑更多的是一维的。

但后来我意识到您可以自定义ItemTemplate的{​​{1}}以包含您自己的TreeView,并且您可以自定义HierarchicalDataTemplate ItemTemplate使用您自己定制的HierarchicalDataTemplate ... Presto!正好两层,每层都有不同的东西!

所以我的观点是DataTemplate足够灵活,你应该尝试不创建自己的自定义控件。

这就是我的所作所为:

XAML:

TreeView

<Page x:Class="Foo.Views.TreePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Foo.Views" xmlns:viewModel="clr-namespace:Foo.ViewModels" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="Tree page" d:DataContext="{d:DesignInstance Type=viewModel:TreeModel}"> <TreeView VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" ScrollViewer.CanContentScroll="True" VirtualizingPanel.ScrollUnit="Pixel" ItemsSource="{Binding Values}"><!-- IList<Person> --> <TreeView.ItemTemplate><!-- Template for first layer, which has a HierarchicalDataTemplate so that this layer will expand --> <HierarchicalDataTemplate ItemsSource="{Binding Expenses}"><!-- IList<Expense> --> <HierarchicalDataTemplate.ItemTemplate><!-- Template for the second layer, which has a DataTemplate instead of HierarchicalDataTemplate so that this layer won't expand --> <DataTemplate> <TextBlock Text="{Binding Amount}"/><!-- Expense amount in dollars --> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> <TextBlock Text="{Binding Name}"/><!-- Person name --> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </Page> 类:

Person

public class Person { public string Name { get; set; } public List<Expense> Expenses { get; set; } } 类:

Expense

以下是它的外观:

Screenshot of the above code in action

我用Snoop检查了它,以证明它是UI虚拟化。这是应用程序较小时加载的public class Expense { public double Amount { get; set; } } 的数量:

Screenshot showing the number of elements when the app is small

...这是应用程序全屏时加载TreeViewItem的数量(它继续超出此代码段,但您明白了):

Screenshot showing that there are more elements when the app is fullscreen

现在只是设计样式的简单问题,使嵌套层看起来像我想要的那样!

编辑:我刚刚确认TreeViewItem虚拟化了所有图层,而不仅仅是第一层。

答案 1 :(得分:0)

我有一个指向虚拟化堆栈面板的列表的链接,但由于某种原因,该页面显示为空白。这是另一个讨论它的页面:

http://www.designerwpf.com/2008/02/12/listview-and-listbox-performance-issues/

甚至链接到我正在谈论的那个,但它总是空白。如果您在该页面上查看Mark Shurmer博客的链接。如果您想尝试,请点击以下链接:

http://itknowledgeexchange.techtarget.com/wpf/listview-is-it-really-too-slow/

Bea Stollnitz也有一些可能有帮助的文章:

Part 1 Part 2 Part 3

如果你发布了一些代码,有人可能会解开一些意大利面条,以帮助你更好地实现。

编辑:找到一个可能有效的链接(谢谢archive.org !!!): http://web.archive.org/web/20080104163725/http://itknowledgeexchange.techtarget.com/wpf/listview-is-it-really-too-slow/