当前位置: 首页 > 知识库问答 >
问题:

WPF TreeView和虚拟化问题

夹谷志
2023-03-14

我有一个树视图与2级层次结构。TreeView项目对特定类的属性有吸引力。基本上,我得到了可观察收藏列表,并将该列表作为我的TreeView ItemsSource。最初,TreeView可见性设置为折叠,并在分配ItemsSource后,TreeView可见性设置为可见。在这一点上,应用程序冻结约40秒(它基本上加载1000个父项目和每个父5-10个孩子)。

贝因德代码是

PopulateTreeView()
{
    // ocListToDisplay is my ObservableCollection
    tvES.ItemsSource = ocListToDisplay;

    //App Freezes at this bit when making the tvES Visible from Collapsed
    tvES.Visibility = System.Windows.Visibility.Visible; 
}

我的XAML是这样的

 <ScrollViewer Name="scContainer" VerticalAlignment="Stretch" 
               HorizontalAlignment="Stretch">
    <StackPanel>
        <StackPanel.Resources>
            <exportImport:TreeViewDashboard x:Key="dataItems"/>
            <HierarchicalDataTemplate DataType="{x:Type exportImport:TreeViewDashboard}"
                                      ItemsSource="{Binding Path=Components}">

                <Grid  Margin="2" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition ></ColumnDefinition>
                        <ColumnDefinition ></ColumnDefinition>
                        <ColumnDefinition ></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <CheckBox Name="checkbx" Grid.Column="0" Margin="2" 
                              Tag="{Binding Path=Tag}" 
                              Checked="OnCheck" Unchecked="OnUnCheck"></CheckBox>
                    <Image Margin="2" Grid.Column="1" Source="{Binding Path=ImageUrl}"  
                           Height="14" Width="16" ></Image>
                    <TextBlock Margin="2" Grid.Column="2" Text="{Binding Path=Name}"
                              FontWeight="Bold" />
                </Grid>

                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <Grid  Margin="2" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition ></ColumnDefinition>
                                <ColumnDefinition ></ColumnDefinition>
                                <ColumnDefinition ></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <CheckBox Name="checkbx" Grid.Column="0" Margin="2" 
                                      Tag="{Binding Path=Tag}" 
                                      Checked="OnCheck" Unchecked="OnUnCheck"/>
                            <Image Margin="2" Grid.Column="1" 
                                   Source="{Binding Path=ImageUrl}" 
                                   Height="14" Width="16" />
                            <TextBlock Margin="2" Grid.Column="2" 
                                  Text="{Binding Path=Name}" FontWeight="Bold" />
                        </Grid>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>

            </HierarchicalDataTemplate>
        </StackPanel.Resources>

        <--same result if you set IsVirtualizing to True/False App freezes for 40 sec-->
        <TreeView Name="tvES"  BorderThickness="0" 
              ItemsSource="{Binding Source={StaticResource dataItems}}"
              VirtualizingStackPanel.IsVirtualizing="False"
              VirtualizingStackPanel.VirtualizationMode="Recycling"
              TreeViewItem.Expanded="item_Expanded"
              TreeViewItem.Collapsed="item_Collapsed" >
            <TreeView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </TreeView.ItemsPanel>
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="False" />
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>
    </StackPanel>  
 </ScrollViewer>

我还试图获取树视图中的视觉对象数量。我得到相同数量的视觉计数在两个情况下的IsVisuize="真"和IsVisuize="假"这清楚地表明我做了错事。

从树中获取可视计数的代码

  //In my case I am passing tvES as  DependencyObject
    private static int GetVisualCount(DependencyObject visual)
    {
        int visualCount = 1;
        int childCount = VisualTreeHelper.GetChildrenCount(visual);

        for (int i = 0; i < childCount; i++)
        {
            DependencyObject childVisual = VisualTreeHelper.GetChild(visual, i);
            visualCount += GetVisualCount(childVisual);
        }

        return visualCount;
    } 

我最终得到了树视图,但问题是我的应用程序在填充树视图时冻结了。。!!有人为此找到工作了吗??我有scollviewer,这会导致虚拟化问题吗?

PS:TreeView生成的是这样的,但是有1000个类似的节点

更新:

我在读关于虚拟化的面板,上面写着——StackPanel中的虚拟化仅在面板中包含的items控件创建其自己的项目容器时发生。您可以通过使用数据绑定来确保这一点。在创建项目容器并将其添加到items控件的情况下,VirtualzingStackPanel与StackPanel相比没有性能优势

有人能告诉我我所遵循的上述方法是否正确吗??我非常确定我是我站错了一边...

共有1个答案

章远航
2023-03-14

您忘记设置ScrollViewer。CanContentScroll=True。这是虚拟化的键。并将isvirtualization返回true

 类似资料:
  • 虚拟化 [PV_OPS] noreplace-paravirt 禁止使用内核通用的半虚拟化接口paravirt_ops,主要用于解决某些在Virtual PC上安装或运行Linux的故障。 [VMMIO] virtio_mmio.device=size@baseaddr:irq[:id] 实例化virtio-mmio设备(CONFIG_VIRTIO_MMIO)。可以多次使用以实例化多个设备。 si

  • 本文向大家介绍完全虚拟化和准虚拟化之间的区别,包括了完全虚拟化和准虚拟化之间的区别的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将了解完全虚拟化和半虚拟化之间的区别 全面虚拟化 此过程由IBM于1966年引入。它被认为是第一个用于服务器虚拟化的软件解决方案。它使用二进制翻译和直接方法。 在这种情况下,使用虚拟机将来宾操作系统与虚拟化层和硬件完全隔离。 完全虚拟化的示例包括Microsof

  • Docker 常用命令 docker pull redis #拉取镜像,默认 latest 版本 docker pull mysql:8.0 #拉取指定版本镜像 docker images #查看镜像 docker image ls #查看镜像 docker image ls -f dangling=true #查看虚悬镜像 docker image prune #删除虚悬镜像 doc

  • 在开发和线上阶段使用不同的系统运行环境的话, 经常会遇到各种各样的 BUG, 并且在团队开发的时候, 让所有成员都保持使用最新版本的软件和类库, 也是一件很让人头痛的事情. 如果你是在 Windows 下开发, 线上环境是 Linux (或者别的非 Windows 系统) 的话, 或者团队协同开发的时候, 建议使用虚拟机. 除了大家熟知的 VMware 和 VirtualBox 外, 还有很多工具

  • I/O虚拟化包括管理虚拟设备和共享的物理硬件之间I/O请求的路由选择。目前,实现I/O虚拟化有三种方式:I/O全虚拟化、I/O半虚拟化和I/O透传。 全虚拟化:宿主机截获客户机对I/O设备的访问请求,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。 半虚拟化:通过前端驱动/后端驱动模拟实现I/O虚拟化。客户机中的驱动程序为前端,宿主机提供的与客

  • JBoss 数据虚拟化平台测试报告 JBoss 数据虚拟化平台测试报告内容包括: 功能性测试 性能指标报告 重要链接 JBoss 数据虚拟化认证配置 - https://access.redhat.com/articles/703663