• 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。

  • 相关阅读:
    Cocos2d-x 3.0截屏功能集成
    游戏嵌入Webview网页
    Cocos2dx进阶学习之屏幕适配
    Android如何实现文件下载并自动安装apk包!!!
    LINQ Select变量定义 Expression<Func<TSource, TResult>>
    StringComparison枚举
    .net core DBFirst 生成Model表结构
    .net core反向工程Model生成 配置机密
    axios下载文件.net Core
    EFCore Database-first深入研究
  • 原文地址:https://www.cnblogs.com/muzizongheng/p/3668450.html
Copyright © 2020-2023  润新知