WPF DataGrid 渲染速度很慢
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6680879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF DataGrid is very slow to render
提问by David Gunther
I have tried using both a customized DataGrid as well as the stock one in WPF. I have tried populating them manually as well as through bindings. In both cases they are slow.
我曾尝试在 WPF 中同时使用自定义的 DataGrid 和库存的 DataGrid。我试过手动填充它们以及通过绑定填充它们。在这两种情况下,它们都很慢。
I have a scenerio where the user clicks on a button and a DataGrid appears with appropriate data. Currently I am in proof of concept mode and just using sample data. I have a DataSet with a table that has 10 rows in it.
我有一个场景,用户单击一个按钮,然后出现一个带有适当数据的 DataGrid。目前我处于概念验证模式并且只使用示例数据。我有一个带有 10 行表的数据集。
If I don't attach any data to the DataGrid when I click the button the empty DataGrid displays pretty much instantly, a user cannot perceive a delay. As soon as I add 10 rows of data, for 6 columns, the delay is about 2 seconds, very noticable to the user.
如果我在单击按钮时没有将任何数据附加到 DataGrid,空的 DataGrid 几乎会立即显示出来,用户不会感觉到延迟。一旦我添加了 10 行数据,对于 6 列,延迟大约是 2 秒,这对用户来说非常明显。
I even tried filling with empty data, just to get an empty grid to appear and it is equally as slow.
我什至尝试填充空数据,只是为了显示一个空网格,而且速度同样慢。
for (int i = 0; i < 10; i++)
_dataGrid.Items.Add("");
I put a timer to count the ticks from when the button is clicked to when all of the code is executed to draw the DataGrid and it is around 20 milliseconds, so the code executes very fast, but on the screen is where the big lag is. I tried a GridView and it renders much fast on the screen.
我放了一个计时器来计算从单击按钮到执行所有代码以绘制 DataGrid 时的滴答声,大约是 20 毫秒,所以代码执行得非常快,但在屏幕上是大滞后的地方. 我尝试了 GridView,它在屏幕上的渲染速度非常快。
I have heard various reports of slow DataGrid drawing with complex scenarios and using 1000's of rows, but this is as simple as it gets, 6 columns by 10 rows filled with empty data.
我听说过各种关于复杂场景下缓慢绘制 DataGrid 并使用 1000 行的报告,但这很简单,6 列 x 10 行填充空数据。
For readonly display is GridView an equally viable option to the DataGrid?
对于只读显示,GridView 是 DataGrid 的同样可行的选择吗?
Update
更新
Here is the creation of my columns.
这是我的专栏的创建。
DataGridTextColumn column = new DataGridTextColumn();
column.ColumnWidthChanged += new ColumnWidthChangedEventHandler(column_ColumnWidthChanged);
column.Header = entity.GetPropertyValue("ColumnLabel");
column.Binding = new Binding(entity.GetPropertyValue("Tag"));
column.Width = new DataGridLength(entity.GetPropertyDouble("DisplaySize"));
_dataGrid.Columns.Add(column);
This is a how I bind the DataSet with 10 rows in it.
这是我将 DataSet 与其中的 10 行绑定的方式。
_dataGrid.ItemsSource = ds.Tables[0].DefaultView;
_dataGrid.DataContext = ds.Tables[0];
Not sure what I can do differently.
不知道我能做些什么不同的。
回答by sll
Are you have:
你有没有:
- Enabled
VirtualizingStackPanel.VirtualizationMode
for a Grid? if not - try to set. - Set VirtualizingStackPanel.IsVirtualizing="true" for DataGrid
- Wrapped up a Grid by a StackPanel container? If yes - try to remove.
- Wrapped up a Grid by an external ScrollViewer control? If yes - try to remove.
VirtualizingStackPanel.VirtualizationMode
为网格启用?如果没有 - 尝试设置。- 为 DataGrid 设置 VirtualizingStackPanel.IsVirtualizing="true"
- 用 StackPanel 容器包装了一个网格?如果是 - 尝试删除。
- 通过外部 ScrollViewer 控件包装了一个 Grid?如果是 - 尝试删除。
One more point, could you bind whole items collection at once instead of adding each item into the grid.Items collection?
还有一点,你能不能一次绑定整个项目集合而不是将每个项目添加到 grid.Items 集合中?
回答by TripleAntigen
A general tip for DataGrid
performance issues: I had a problem with the DataGrid in which it took literally seconds to refresh after a window resize, column sort, etc. and locked up the window UI while it was doing so (1000 rows, 5 columns).
关于DataGrid
性能问题的一般提示:我遇到了 DataGrid 的问题,其中在调整窗口大小、列排序等后需要几秒钟才能刷新,并且在执行此操作时锁定了窗口 UI(1000 行,5 列) .
It came down to an issue (bug?) with the WPF sizing calculations. I had it in a grid with the RowDefinition
Height="Auto"
which was causing the rendering system to try and recalculate the size of the DataGrid at runtime by measuring the size of each and every column and row, presumably by filling the whole grid (as I understand it). It is supposed to handle this intelligently somehow but in this case it was not.
这归结为 WPF 大小计算的问题(错误?)。我将它放在一个网格中,RowDefinition
Height="Auto"
这导致渲染系统在运行时尝试通过测量每一列和每一行的大小来重新计算 DataGrid 的大小,大概是通过填充整个网格(据我所知)。它应该以某种方式智能地处理这个问题,但在这种情况下它不是。
A quick check to see if this is a related problem is to set the Height
and Width
properties of the DataGrid to a fixed size for the duration of the test, and try running again. If your performance is restored, a permanent fix may be among these options:
快速检查这是否是相关问题是在测试期间将 DataGrid的Height
和Width
属性设置为固定大小,然后再次尝试运行。如果您的性能恢复,永久修复可能是以下选项之一:
- Change the sizes of the containing elements to be relative (*) or fixed values
- Set
MaxHeight
andMaxWidth
of the DataGrid to a fixed value larger than it could get in normal use - Try another container type with different resizing strategy (
Grid
,DockPanel
, etc)
- 将包含元素的大小更改为相对 (*) 或固定值
- 将DataGrid 的
MaxHeight
和设置MaxWidth
为比正常使用时更大的固定值 - 尝试用不同的大小调整战略的另一个容器类型(
Grid
,DockPanel
,等)
回答by Damn Vegetables
A blogI found on Google gave me a sort-of solution. As the author said, I disabled GroupStyle, and the rendering speed issue was solved. But I needed grouping. The author said
我在谷歌上找到的一个博客给了我一种解决方案。正如作者所说,我禁用了GroupStyle,解决了渲染速度问题。但我需要分组。作者说
VirtualizingPanel.IsVirtualizingWhenGrouping
is added to .NET 4.5. So I set it to true. Now rendering is quick with grouping. The problem is... scrolling is jerky. Not unacceptably jerky, but noticeably jerky. I had similar problem when I tried to create a TreeView with 2000+ nodes expanded. Without virtualisation, rendering was slow but scrolling was smooth. With virtualisation, rendering was quick but scrolling was jerky.
添加到 .NET 4.5。所以我把它设置为true。现在通过分组可以快速渲染。问题是......滚动是生涩的。不是不可接受的生涩,而是明显的生涩。当我尝试创建一个扩展了 2000 多个节点的 TreeView 时,我遇到了类似的问题。没有虚拟化,渲染很慢,但滚动很流畅。使用虚拟化,渲染很快,但滚动很不稳定。
Why can't we have both...
为什么我们不能同时拥有...
回答by Evalds Urtans
In my case I had a problem with DataGridCell ControlTemplate that slowed rendering way down.
在我的情况下,我遇到了 DataGridCell ControlTemplate 的问题,这会减慢渲染速度。
Be aware that relative loading speeds for large dataset are very different for using TextBlock(that is not selectable text) or TextBoxin ReadOnly mode:
请注意,在 ReadOnly 模式下使用TextBlock(非可选文本)或TextBox时,大型数据集的相对加载速度非常不同:
Loading time 59 seconds:
加载时间 59 秒:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox IsReadOnly="True" Text="{Binding Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Loading time 21 seconds:
加载时间 21 秒:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Loading time 16 seconds:
加载时间 16 秒:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBlock Text="{Binding}"></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
回答by Nirav Raval
Well a little bit adding more (i know its very old topic, but still it helps someone)...
好吧,添加更多(我知道它很老的话题,但它仍然对某人有帮助)...
I tried
我试过
EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True"
for DataGrid(AutoGenerateColumns="True"
) binding to DataTable.DefaultView() and No effect on speed, it was still horrible for Speed as well as for navigation between rows. Than, I came up with solution to set Fixed Height and Width of DataGrid. Additionally I also set
对于 DataGrid( AutoGenerateColumns="True"
) 绑定到 DataTable.DefaultView() 并且对速度没有影响,对于速度以及行之间的导航来说仍然很糟糕。然后,我想出了设置 DataGrid 的固定高度和宽度的解决方案。另外我还设置了
RowHeight="23"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
This makes my page fill very fast... Instead of 2 min, now it takes hardly 10-12 seconds.
这使我的页面填充非常快......而不是 2 分钟,现在几乎不需要 10-12 秒。
Hope it helps someone.
希望它可以帮助某人。
Note: I am using .Net 4.5
注意:我使用的是 .Net 4.5
回答by Nick
I was having big issues with 1000 rows, 5 columns where the render time was taking 7-10 seconds, but the solution found at https://www.elegant-software.net/2014/05/performance-of-the-wpf-datagrid.htmlmade the grid load instantly!
我遇到了 1000 行、5 列的大问题,其中渲染时间需要 7-10 秒,但在https://www.elegant-software.net/2014/05/performance-of-the-wpf 上找到了解决方案-datagrid.html立即加载网格!
<DataGrid
EnableRowVirtualization="True"
EnableColumnVirtualization="True">
回答by waxingsatirical
For me it was:
对我来说是:
<Setter Property='ScrollViewer.CanContentScroll' Value='False' />
I removed this from the style and the rendering became fast.
我从样式中删除了它,渲染变得很快。
回答by user3515346
I have a Surface Pro 3 on which my datagrid, with about 200 rows and 10 columns, was really slow at scrolling, jerky and hesitant.
我有一个 Surface Pro 3,我的数据网格大约有 200 行和 10 列,在滚动、生涩和犹豫时真的很慢。
I thought it was the network, but it was in fact the graphics card not being able to keep up with - wait for it - a drop shadow effect on the datagrid itself, even though the background of the control was set to a solid colour.
我以为是网络问题,但实际上是显卡无法跟上 - 等待 - 数据网格本身的阴影效果,即使控件的背景设置为纯色。
I commented out the effect and it was 4-5 times faster.
我注释掉了效果,速度提高了 4-5 倍。
Hope this helps.
希望这可以帮助。
回答by SLAVICA
I have same problem with bound Data grid, and I notice that in first load it is fast but on secand and next it is slow. So when I add in code
我对绑定数据网格有同样的问题,我注意到在第一次加载时它很快,但在第二次加载时它很慢。所以当我添加代码时
DataGrid.ItemsSource = Nothing
and then TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure
it became very FAST
DataGrid.ItemsSource = Nothing
然后TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure
它变得非常快