2

我已经把自己编码成一个泡菜。我正在编写一个自定义 WPF 控件,该控件类似于此 MSDN 文章 以及网络上的许多其他地方中TreeListView 描述的内容。在这一点上,这个东西的很大一部分是定制的,它很好地满足了我的目标,除了在虚拟化方面。我的覆盖和模板都使用s 来呈现它们的项目,并且我已经验证所有这些都按预期创建。虚拟化在根级项目上正常工作(只有当前可见的那些 UI 元素被煮熟),并且TreeViewTreeViewItemVirtualizingStackPanelScrollViewerTreeViewstuff 负责不为折叠节点生成元素。扩展节点时会出现问题——所有元素都是为节点中的每个子节点制作的,即使是屏幕外的数千个元素。

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

不幸的是,如果没有虚拟化发生,这件事就像泥巴一样慢,所以我需要想出某种解决方案。任何建议将不胜感激。

4

2 回答 2

2

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

就我而言,我认为 aTreeView不会削减它,因为我需要正好两层,并且两层之间显示的项目类型不同。另外,我正在重构一个Expanders 列表,所以我更加一维地思考。

但是后来我意识到您可以自定义 的ItemTemplateTreeView包含您自己的HierarchicalDataTemplate,并且您可以使用自己量身定制的ItemTemplate... Presto!正好两层,每一层都有不同的东西!HierarchicalDataTemplateDataTemplate

所以我的观点是TreeView足够灵活,你应该尽量不要创建自己的自定义控件。

这是我所做的:

XAML:

<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班级:

public class Expense
{
    public double Amount { get; set; }
}

这是它的外观:

上述代码的截图

我用Snoop检查了它以证明它是 UI 虚拟化。TreeViewItem这是应用较小时的加载次数:

显示应用较小时元素数量的屏幕截图

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

显示应用全屏时有更多元素的屏幕截图

现在只需简单地设置样式即可使嵌套层看起来像我想要的那样!

编辑:我刚刚验证TreeView虚拟化了它的所有层,而不仅仅是第一层。

于 2017-03-16T18:47:41.843 回答
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 也有一些文章可能会有所帮助:

第 1 部分 第 2 部分 第 3 部分

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

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

于 2009-07-30T20:17:26.403 回答