WPF DataGrid渲染速度很慢

时间:2011-07-13 14:52:48

标签: wpf performance datagrid render

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

我有一个场景,用户点击一个按钮,DataGrid会显示适当的数据。目前我在概念模式的证明,只使用样本数据。我有一个DataSet,其中有一个包含10行的表。

如果我在单击按钮时没有将任何数据附加到DataGrid,则空DataGrid会立即显示,用户无法察觉延迟。一旦我添加10行数据,对于6列,延迟大约为2秒,这对用户来说非常明显。

我甚至尝试填充空数据,只是为了显示一个空网格,它同样慢。

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

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

我听过各种关于使用复杂场景和使用1000行的DataGrid绘图速度慢的报告,但这很简单,6列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);

这是我将DataSet与10行绑定的方式。

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

不确定我能做些什么不同。

11 个答案:

答案 0 :(得分:31)

你有:

  • 为网格启用VirtualizingStackPanel.VirtualizationMode?如果不是 - 尝试设置。
  • 为DataGrid设置VirtualizingStackPanel.IsVirtualizing =“true”
  • StackPanel容器包装网格?如果是 - 请尝试删除。
  • 通过外部ScrollViewer控件包装网格?如果是 - 请尝试删除。

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

答案 1 :(得分:23)

DataGrid性能问题的一般提示:我在使用DataGrid时遇到问题,在窗口调整大小,列排序等等之后,它花了几秒钟的时间来刷新,并且在它正在执行时锁定了窗口UI所以(1000行,5列)。

使用WPF大小计算得出问题(bug?)。我在RowDefinition Height="Auto"的网格中得到它,这导致渲染系统尝试通过测量每个列和行的大小来重新计算DataGrid的大小,可能是通过填充整个网格(据我所知)。它应该以某种方式智能地处理它,但在这种情况下它不是。

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

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

答案 2 :(得分:12)

A blog我在Google上发现了一种解决方案。正如作者所说,我禁用了GroupStyle,解决了渲染速度问题。但我需要分组。作者说

VirtualizingPanel.IsVirtualizingWhenGrouping

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

为什么我们不能同时拥有......

答案 3 :(得分:10)

在我的情况下,我遇到了DataGridCell ControlTemplate的问题,这会减慢渲染速度。

请注意,在ReadOnly模式下使用 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>

答案 4 :(得分:3)

好一点添加更多(我知道它非常古老的主题,但它仍然有助于某人)......

我试过

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

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

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

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

希望它有所帮助。

注意:我使用的是.Net 4.5

答案 5 :(得分:1)

我有一个Surface Pro 3,我的数据网格,大约有200行和10列,在滚动,生涩和犹豫时非常慢。

我认为这是网络,但事实上显卡无法跟上 - 等待它 - 对数据网格本身产生阴影效果,即使控件的背景设置为纯色。

我评论了效果,它的速度提高了4-5倍。

希望这有帮助。

答案 6 :(得分:1)

我对绑定的数据网格有同样的问题,我注意到在第一次加载时它很快但在秒和下一步它很慢。所以当我添加代码时

DataGrid.ItemsSource = Nothing然后TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure变得非常快

答案 7 :(得分:1)

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

1

答案 8 :(得分:0)

对我而言:

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

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

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

如果你有像 belove 这样的行定义:

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

你必须小心!例如,如果您的 Datagrid 在这些行之一中,那么它将一遍又一遍地为每一行调整大小。如果您有 1000 行,那么它的大小将是您的 Datagrid 的 1000 倍!

让我们告诉您的 Datagrid 在第 3 个 RowDefinition 中,那么我建议您以这种方式更改代码。

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

当然,您也可以随意更改“400”。