我有点把自己编成了这个腌菜。我正在编写一个自定义WPF控件,它类似于This MSDN article中描述的TreeListView
以及网上的许多其他位置。在这一点上,相当大的一件事是定制的,除了在虚拟化方面,它还能很好地实现我的目标。我的覆盖TreeView
和TreeViewItem
模板都使用VirtualizingStackPanel
来展示他们的项目,并且我已经验证所有这些都是按预期创建的。虚拟化在根级别项目上正常工作(只有ScrollViewer
中当前可见的UI元素已经生成),TreeView
内容负责不生成折叠节点的元素。扩展节点时会出现问题 - 所有元素都为节点中的每个子节点制作,甚至是屏幕外的数千个节点。
在我看来,我需要做的就是以某种方式将内部嵌套VirtualizingStackPanel
的scrollowner属性设置为默认情况下根级别VSP连接到的相同主滚动视图,但我读了一个MSFT海报here说这不起作用。
不幸的是,这个东西很慢,因为没有虚拟化的泥浆,所以我需要提出某种解决方案。任何建议都将不胜感激。
答案 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
以下是它的外观:
我用Snoop检查了它,以证明它是UI虚拟化。这是应用程序较小时加载的public class Expense
{
public double Amount { get; set; }
}
的数量:
...这是应用程序全屏时加载TreeViewItem
的数量(它继续超出此代码段,但您明白了):
现在只是设计样式的简单问题,使嵌套层看起来像我想要的那样!
编辑:我刚刚确认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也有一些可能有帮助的文章:如果你发布了一些代码,有人可能会解开一些意大利面条,以帮助你更好地实现。
编辑:找到一个可能有效的链接(谢谢archive.org !!!): http://web.archive.org/web/20080104163725/http://itknowledgeexchange.techtarget.com/wpf/listview-is-it-really-too-slow/