【问题标题】:WPF DataGrid performance concernsWPF DataGrid 性能问题
【发布时间】:2010-06-11 13:03:27
【问题描述】:

我正在测试 WPF DataGrid,希望能替换一些 winforms 控件,到目前为止,我对开发过程非常满意。性能似乎是我现在最关心的问题。我的开发工作站拥有市场上运行 Windows 7 的最佳 CPU,配备 6 GB 的 DDR3 内存。我要替换的 Windows 控件的响应速度要快得多,这令人担忧。

我的测试是绑定到 ObservableCollection 的 DataGrid 的基本实现,每秒更新一次。它还包括详细信息区域,可扩展以显示有关每行的更多信息。详细信息区域只是一个带有 ItemsControl 包装 TextBlock 的堆栈面板(重复 6 次)

我的抱怨是,如果我尝试滚动此集合,它通常会因延迟而生涩,如果我尝试在每一行进入时展开它们,大约 15% 的点击不会触发按钮点击事件(DataGridTmplateColumn > CellTemplate > 数据模板 > 按钮) 如果某些行细节被展开(滚动条会在向上/向下调整大小时自行调整大小),滚动也会更加紧张

有哪些需要寻找/优化/避免的东西?

更新

到目前为止,我发现以下几点很有帮助:

  • 尽可能少地依赖动态布局。由于每个组件都包含许多子组件,并且在动态布局世界中,它们都必须调用 Measure 和 Layout 方法,这可能是 CPU 密集型的。所以代替列宽自动(或没有指定宽度),使用固定宽度

  • 安装 WPF Performance Suite 并了解您的应用程序是如何呈现的。非常棒的应用程序

  • 正如 Andrew 指出的那样,ListView 是一个很好的选择,因为当您不需要高级 DataGrid 功能时,例如更新数据或可能的详细信息视图(我仍然希望重现)

  • SuspendableObservableCollection 也非常适合在很短的时间内添加多个项目(即 0.01 秒内添加 100 个项目等)

  • 经过大量测试,我发现 BindingList 比 ObservableCollection 快得多。我发布了由 BindingList 与 Observable 集合处理的相同负载的性能分析器快照here,前者占用的 CPU 时间不到一半。 (请记住,这不仅仅是收集性能,而是与 ListView 配对时)

我的搜索仍在继续,因为我的应用程序中似乎有一些东西正在泄漏内存并在几个小时后将其减慢到停止。

【问题讨论】:

  • 每秒更新一次的内容是什么? ObservableCollection?它是如何更新的(添加项目、全部替换、删除项目等)?
  • _myObservableCollection.Insert(0, newItem)

标签: c# .net wpf performance


【解决方案1】:

关于 DataGrid 性能问题的一般提示:我遇到了 DataGrid 的问题,在该问题中,在调整窗口大小、列排序等之后需要几秒钟才能刷新,并且在执行此操作时锁定了窗口 UI(1000 行, 5 列)。

这归结为 WPF 大小计算的问题(错误?)。我将它放在 RowDefinition Height="Auto" 的网格中,这导致渲染系统在运行时尝试通过测量每一列和每一行的大小来重新计算 DataGrid 的大小,大概是通过填充整个网格(据我了解)。它应该以某种方式智能地处理这个问题,但在这种情况下它不是。

快速检查这是否是相关问题是在测试期间将 DataGrid 的 Height 和 Width 属性设置为固定大小,然后再次尝试运行。如果您的性能得到恢复,则可以使用以下选项进行永久性修复:

  • 将包含元素的大小更改为相对 (*) 或 固定值
  • 将 DataGrid 的 MaxHeight 和 MaxWidth 设置为更大的固定值 比正常使用时更容易
  • 尝试使用不同大小调整策略(Grid、DockPanel 等)的其他容器类型

【讨论】:

    【解决方案2】:

    您是指 WPF Toolkit 中的 DataGrid 吗?如果是,在我看来它很慢,所以我最终将 ListView 与 GridView 一起使用。

    【讨论】:

    • 是的,但在 4.0 中它是框架的一部分。我会试试看.. 但是我会如何显示/隐藏行详细信息?
    • ListView中没有RowDetails,当然你可以尝试通过ControlTemplates来实现,但是比较麻烦。因此,如果您迫切需要 RowDetails,最好使用 DataGrid 控件的设置。
    【解决方案3】:

    更一般的提示:

    对于滚动,我们所做的是尝试使用延迟滚动。

    为了提高过滤性能,您可以考虑自己过滤绑定的集合。

    对于具有大量列的网格,也应用 ColumnVirtualization。这往往会对水平滚动产生一些不利影响,但您可以测试您的场景并应用改进。对我们来说,它确实工作得很好。它帮助我们处理大型网格的刷新、重新加载、渲染场景。

    应用的样式也会影响性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-18
      • 2010-12-14
      • 1970-01-01
      • 2013-04-21
      • 2011-05-04
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      相关资源
      最近更新 更多