最近在帮同事调试一个类似资源管理器的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。

最新文章

  1. just555 对话
  2. angularJS: shop chart
  3. BZOJ 3176 Sort
  4. Netty是什么?
  5. Java 对象内存分配与回收
  6. Maven exclusion
  7. 如何给10^7个数据量的磁盘文件排序--bitset
  8. ckfinder动态指定上传路径
  9. easyui源码翻译1.32--DateBox(日期输入框)
  10. ajax跨域访问 webservice
  11. activemq下activemq.bat不能启动
  12. [转]设置Jupyter-Notebook表格打印多个变量的值
  13. 【Linux】 升级CentOS6的内核到3.10
  14. Python学习基本小练习
  15. Spring Security(二十七):Part II. Architecture and Implementation
  16. github 快速部署
  17. git 的相关知识
  18. 函数:this &amp; return、break、continue、exit()
  19. Abstractive Summarization
  20. poj2586 【贪心】

热门文章

  1. DNS 主从同步配置
  2. 基于Visual c++ 2012的php扩展开发 - 环境搭建
  3. MySQL备份账号权限
  4. 《机器学习基石》第一周 —— When Can Machine Learn?
  5. 基于docker环境,搭建 jetty环境, 部署java项目
  6. VC 写注册表
  7. mini6410基于linux2.6.36内核通过NFS启动根文件系统总结(一搭建开发环境——建立NFS服务器)
  8. 命令行编译vs10项目工程
  9. 深入理解Servlet3.0异步请求
  10. Spring Boot入门——全局异常处理