zoukankan      html  css  js  c++  java
  • TreeView的性能问题

    最近在帮同事调试一个类似资源管理器的wpf界面,左边TreeView去遍历大目录时UI卡死,刚开始我以为是在UI线程中调用系统API遍历目录的原因,就改为后台遍历,但是没有效果。

    根本原因:
    TreeView的Style中Template对于ScrollViewer的CanContentScroll设置为FALSE, 导致VirtualizingStackPanel的虚拟化失效

    解决办法:
    设置ScrollViewer的CanContentScroll为True,

    如:
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type TreeView}">
    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
    <ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
    <ItemsPresenter/>
    </ScrollViewer>
    </Border>
    <ControlTemplate.Triggers>
    <Trigger Property="IsEnabled" Value="false">
    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    </Trigger>
    <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
    <Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
    </Trigger>
    </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    <Style.Triggers>
    <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
    <Setter Property="ItemsPanel">
    <Setter.Value>
    <ItemsPanelTemplate>
    <VirtualizingStackPanel/>
    </ItemsPanelTemplate>
    </Setter.Value>
    </Setter>
    </Trigger>
    </Style.Triggers>


    背景知识:
    1. CanContentScroll主要用为控制当前itemsControl的滚动方式:逻辑滚动(True)和物理滚动(False)。

    所谓逻辑滚动,就是点击滚动条每次最小单位为itemsControl中的每个Item的高度或者宽度。
    而物理滚动,就是点击滚动条每次以物理像素(pixel)进行滚动。

    2.一般我们在用ItemsControl时都会设置ItemsPanel为VirtualizingStackPanel或者类似虚拟化容器,并且把虚拟化标记IsVirtualizing打开, 但是有几种情况会导致界面上的虚拟化被禁止:

    • 项容器直接添加到 ItemsControl。 例如,如果应用程序将 ListBoxItem 对象显式添加到 ListBox,则 ListBox 不会虚拟化 ListBoxItem 对象。
    • ItemsControl 中的项容器属于不同类型。 例如,使用 Separator 对象的 Menu 无法实现项回收,因为 Menu 包含 Separator 和 MenuItem 类型的对象。
    • 将 CanContentScroll 设置为 false。
    • 将 IsVirtualizing 设置为 false。

  • 相关阅读:
    日常学习随笔-数组、单链表、双链表三种形式实现队列结构的基本操作(源码注释)
    代码重构之单元测试
    C# yield return 用法与解析
    MVC学习手册之数据注解与验证
    C#数字图像处理算法学习笔记(三)--图像几何变换
    关于变量名与类名同名问题
    C# 计时器
    C#入门--索引器
    C#入门--字段与属性
    var与dynamic
  • 原文地址:https://www.cnblogs.com/muzizongheng/p/3668450.html
Copyright © 2011-2022 走看看