【问题标题】:DataGrid in a StackPanel leads to OutOfMemoryExceptionStackPanel 中的 DataGrid 导致 OutOfMemoryException
【发布时间】:2010-09-15 13:06:24
【问题描述】:

我在 WPF 窗口中有网格,里面有一个 DataGrid 控件:

<Grid>
    <DataGrid ItemsSource="{Binding AllAuthors}" />
</Grid>

AllAuthorsObservableCollection&lt;Author&gt;Author 一个只有几个字符串属性的简单类。该集合在后面的代码中填充了大约 40000 个对象。 DataGrid 会很快打开(1 秒后),并且通过 datagrid 的导航非常顺畅和快速。该应用程序的内存负载为 35 MB。

如果我将上面的代码替换为 ...

<StackPanel>
    <DataGrid ItemsSource="{Binding AllAuthors}" />
</StackPanel>

...当应用程序尝试显示 DataGrid 时,应用程序以 100% 的 CPU 负载运行,内存不断增长到 1.5 GB。最后我收到了OutOfMemoryException

我是 WPF 初学者,现在想知道这里出了什么问题。 (我使用的是 VS2010、.NET 4.0 和 WPF 4.0 的内置 DataGrid 控件)

提前感谢您的帮助!

【问题讨论】:

  • 你帮我找到了我的问题:我使用 Task.run() 管理所有内容,当我“更新”我的收藏并提高 OnPropertyChanged() 时,该工具同样崩溃行为(最大 RAM,outofMemoryException)。我搜索了几个小时以了解我的 c# 代码中出了什么问题,但最后,这是由于 UI 线程创建了一个巨大的堆栈面板!谢谢

标签: wpf datagrid wpfdatagrid stackpanel


【解决方案1】:

只要它在网格中,这不是问题,因为实际上可能只生成了少数项目 - 当前实际可见的项目。这称为 UI 虚拟化,并内置在 WPF 中的多个 ItemsControl 中。由于DataGrid比较小,实际生成的Item并不多。

但是,当您将其放入 StackPanel 时,您可能已经构建了一个布局,其中 StackPanel 扩展到 DataGrid 的高度,而 DataGrid 占用了它认为需要的空间。我们需要查看完整的 xaml 以查看是否是这种情况。无论如何,如果是的话,现在实际上有很多“可见”的项目(即所有项目)。而生成 40000 个项目显然不是一个好主意。

您比较过两个 DataGrid 的 ActualHeight 属性吗?

【讨论】:

  • 感谢您的回复!我刚刚比较了 Grid 和 StackPanel 布局的 ActualHeight(仅 500 个项目),你是对的:如果 DataGrid 在 Grid 中,高度只有 440,如果在 StackPanel 中,它会增长到 8800 以上。我我还在 DataGrid 上设置了EnableRowVirtualization=False 进行测试,在这种情况下,我在 Grid 布局中遇到了相同的内存和性能问题。我不明白为什么我的内存负载超过 1,5 GB。 Author 对象的大小小于 200 字节,那么对于 40000 个对象,1.5 GB 来自哪里?
  • 这来自基于 ItemTemplate 为每个 Author 项目生成的所有 WPF 视觉对象。
  • 好的,我明白了。我现在在 DataGrid 上指定了 400 的Height,现在它也可以与 StackPanel 一起使用。因此,如果我的结论正确,Grid 将网格内部的控件限制在可见窗口区域,而StackPanel 可以根据内部不同控件的需要增长到窗口的不可见区域。是对的吗?无论如何,你的回答很有帮助。再次感谢!
  • 这取决于 Grid/StackPanel 的父级是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 2016-12-02
相关资源
最近更新 更多