WPF DataGrid 渲染速度非常慢

发布于 2024-11-20 00:15:05 字数 1366 浏览 5 评论 0原文

我尝试过使用自定义的 DataGrid 以及 WPF 中的库存 DataGrid。我尝试过手动以及通过绑定填充它们。在这两种情况下,它们都很慢。

我有一个场景,用户单击按钮,就会出现一个包含适当数据的 DataGrid。目前我处于概念验证模式并且仅使用示例数据。我有一个数据集,其中有一个表,其中有 10 行。

如果我在单击按钮时没有将任何数据附加到 DataGrid,空的 DataGrid 几乎会立即显示,用户无法感知到延迟。当我添加 10 行数据,6 列时,延迟约为 2 秒,对用户来说非常明显。

我什至尝试填充空数据,只是为了出现一个空网格,但速度同样慢。

for (int i = 0; i < 10; i++)
    _dataGrid.Items.Add("");

我设置了一个计时器来计算从单击按钮到执行所有代码以绘制 DataGrid 的时间间隔,大约 20 毫秒,因此代码执行速度非常快,但在屏幕上是较大滞后的地方。我尝试了 GridView,它在屏幕上的渲染速度非常快。

我听说过各种有关复杂场景和使用 1000 行的 DataGrid 绘制速度缓慢的报告,但这很简单,6 列 x 10 行填充了空数据。

对于只读显示,GridView 是否是与 DataGrid 同等可行的选项?


更新

这是我的专栏的创建。

                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);

这是我绑定包含 10 行的数据集的方法。

                _dataGrid.ItemsSource = ds.Tables[0].DefaultView;
                _dataGrid.DataContext = ds.Tables[0];

不确定我能做些什么不同的事情。

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.

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.

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.

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.

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.

For readonly display is GridView an equally viable option to the 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.

                _dataGrid.ItemsSource = ds.Tables[0].DefaultView;
                _dataGrid.DataContext = ds.Tables[0];

Not sure what I can do differently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

梦与时光遇 2024-11-27 00:15:06

我有一台 Surface Pro 3,其中的数据网格大约有 200 行和 10 列,滚动速度非常慢、不稳定且犹豫。

我以为是网络的问题,但实际上是显卡无法跟上 - 等等 - 数据网格本身的阴影效果,即使控件的背景设置为纯色。

我把效果注释掉了,速度快了4-5倍。

希望这有帮助。

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.

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.

Hope this helps.

所谓喜欢 2024-11-27 00:15:06

我对绑定数据网格有同样的问题,我注意到在第一次加载时速度很快,但在第二次和接下来加载时速度很慢。因此,当我添加代码

DataGrid.ItemsSource = Nothing ,然后添加 TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure 时,它变得非常快速地

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

回梦 2024-11-27 00:15:06

我的问题是我在 DataGrid 上设置了 ScrollViewer.CanContentScroll="False" 。这会同时禁用 DataGrid 的虚拟化。有关此内容的更多信息,请访问:

https://stackoverflow.com/a/372​​4695/4383302

My problem was that I had ScrollViewer.CanContentScroll="False" set on my DataGrid. This disables virtualization all together for the DataGrid. More info about this can be found here:

https://stackoverflow.com/a/3724695/4383302

一指流沙 2024-11-27 00:15:06

如果您有如下所示的行定义:

 <Grid.RowDefinitions>
    <RowDefinition x:Name="topRow" Height="*"/>
    <RowDefinition x:Name="mainRow" Height="*"/>
    <RowDefinition x:Name="dataGridRow" Height="*"/>
 </Grid.RowDefinitions>

您必须小心!如果您的 DataGrid 位于这些行之一,那么它将一遍又一遍地调整每一行的大小。如果有 1000 行,那么它将调整大小 1000 倍!

现在假设您的 DataGrid 位于第三个 RowDefinition 中,那么我建议您这样更改代码:

     <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="400"/>
    </Grid.RowDefinitions>

当然,您可以按照您的意愿更改 "400"

If you have a row definition like below:

 <Grid.RowDefinitions>
    <RowDefinition x:Name="topRow" Height="*"/>
    <RowDefinition x:Name="mainRow" Height="*"/>
    <RowDefinition x:Name="dataGridRow" Height="*"/>
 </Grid.RowDefinitions>

You must be careful! If your DataGrid is in one of these rows, then it will be resized for every row over and over again. If you have 1000 rows, then it will be resized 1000 times!

Now assume that your DataGrid is in the 3rd RowDefinition then I suggest you change the code this way:

     <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="400"/>
    </Grid.RowDefinitions>

Of course, you can change "400" how you wish.

睫毛上残留的泪 2024-11-27 00:15:05

您是否已:

  • 为网格启用VirtualizingStackPanel.VirtualizationMode?如果没有 - 尝试设置。
  • 为 DataGrid 设置 VirtualizingStackPanel.IsVirtualizing="true"
  • 由 StackPanel 容器包裹网格?如果是 - 尝试删除。
  • 用外部 ScrollViewer 控件包装网格?如果是 - 尝试删除。

还有一点,
您可以一次绑定整个项目集合,而不是将每个项目添加到 grid.Items 集合中吗?

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.

One more point,
could you bind whole items collection at once instead of adding each item into the grid.Items collection?

不顾 2024-11-27 00:15:05

DataGrid 性能问题的一般提示:我遇到了 DataGrid 的问题,在调整窗口大小、列排序等操作后,它实际上需要几秒钟的时间才能刷新,并在执行时锁定窗口 UI所以(1000 行,5 列)。

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

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

  • 将包含元素的大小更改为相对大小 (*) 或
    固定值
  • 将DataGrid的MaxHeightMaxWidth设置为较大的固定值
    比正常使用时可以得到的
  • 尝试使用不同的调整大小策略的另一种容器类型(Grid
    DockPanel等)

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).

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.

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:

  • Change the sizes of the containing elements to be relative (*) or
    fixed values
  • Set MaxHeight and MaxWidth 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)
忆伤 2024-11-27 00:15:05

我在 Google 上发现的一个博客给出了我的一个解决方案。正如作者所说,我禁用了GroupStyle,渲染速度问题就解决了。但我需要分组。作者说

VirtualizingPanel.IsVirtualizingWhenGrouping

是添加到.NET 4.5中的。所以我把它设置为true。现在通过分组渲染速度很快。问题是……滚动很不稳定。不是不可接受的生涩,而是明显的生涩。当我尝试创建一个扩展了 2000 多个节点的 TreeView 时,我遇到了类似的问题。如果没有虚拟化,渲染速度很慢,但滚动很流畅。通过虚拟化,渲染速度很快,但滚动却很不稳定。

为什么我们不能两者兼得...

A blog I 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

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.

Why can't we have both...

咆哮 2024-11-27 00:15:05

就我而言,我遇到了 DataGridCell ControlTemplate 的问题,导致渲染速度减慢。

请注意,在只读模式下使用 TextBlock(即不可选择的文本)或 TextBox 时,大型数据集的相对加载速度有很大不同:

加载时间 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>

加载时间 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>

加载时间 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>

In my case I had a problem with DataGridCell ControlTemplate that slowed rendering way down.

Be aware that relative loading speeds for large dataset are very different for using TextBlock (that is not selectable text) or TextBox in ReadOnly mode:

Loading time 59 seconds:

<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:

<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:

<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>
情释 2024-11-27 00:15:05

好吧,添加更多内容(我知道它非常古老的主题,但仍然对某人有帮助)...

我尝试

EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True" 

将 DataGrid(AutoGenerateColumns="True") 绑定到 DataTable.DefaultView() 并且没有对速度的影响,对于速度以及行之间的导航来说仍然很糟糕。然后,我想出了设置 DataGrid 固定高度和宽度的解决方案。另外我还设置了

RowHeight="23" 
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"

这使得我的页面填充速度非常快...而不是 2 分钟,现在几乎只需要 10-12 秒。

希望它能帮助某人。

注意:我使用的是.Net 4.5

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

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.

Hope it helps someone.

Note: I am using .Net 4.5

暮光沉寂 2024-11-27 00:15:05

对我来说是:

<Setter Property='ScrollViewer.CanContentScroll' Value='False' />

我从样式中删除了它,渲染变得很快。

For me it was:

<Setter Property='ScrollViewer.CanContentScroll' Value='False' />

I removed this from the style and the rendering became fast.

·深蓝 2024-11-27 00:15:05

我遇到了 1000 行 5 列的大问题,渲染时间需要 7-10 秒,但解决方案在 https://www.elegant-software.net/2014/05/performance-of-the-wpf-datagrid.html 使网格立即加载!

<DataGrid
   EnableRowVirtualization="True"
   EnableColumnVirtualization="True">

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.html made the grid load instantly!

<DataGrid
   EnableRowVirtualization="True"
   EnableColumnVirtualization="True">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文