WPF DataGrid渲染速度非常慢

WPF DataGrid渲染速度非常慢,wpf,performance,datagrid,render,Wpf,Performance,Datagrid,Render,我尝试过在WPF中使用定制的DataGrid和库存DataGrid。我尝试过手动填充它们以及通过绑定填充它们。在这两种情况下,它们都很慢 我有一个场景,用户点击一个按钮,就会出现一个带有适当数据的数据网格。目前我处于概念验证模式,仅使用示例数据。我有一个数据集,其中有一个表,其中有10行 _dataGrid.ItemsSource = ds.Tables[0].DefaultView; _dataGrid.DataContext =

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

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

                _dataGrid.ItemsSource = ds.Tables[0].DefaultView;
                _dataGrid.DataContext = ds.Tables[0];
如果在单击按钮时没有将任何数据附加到DataGrid,则空DataGrid会立即显示,用户无法感知延迟。只要我添加10行数据(6列),延迟大约为2秒,用户非常容易注意到

我甚至试着用空数据填充,只是为了得到一个空的网格,它同样慢

for (int i = 0; i < 10; i++)
    _dataGrid.Items.Add("");
这是我如何将数据集绑定到其中10行的一个示例

                _dataGrid.ItemsSource = ds.Tables[0].DefaultView;
                _dataGrid.DataContext = ds.Tables[0];
不确定我能做什么不同的事。

你有:

  • 是否启用网格的虚拟化模式?如果没有-尝试设置
  • 为DataGrid设置virtualzingstackpanel.isvirtualization=“true”
  • 用StackPanel容器包裹网格?如果是-尝试删除
  • 通过外部ScrollViewer控件包装网格?如果是-尝试删除
还有一点,
您是否可以一次绑定整个项目集合,而不是将每个项目添加到网格中。项目集合?

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

这归结为WPF大小计算的一个问题(bug?)。我把它放在带有
行定义
的网格中,这导致渲染系统试图在运行时通过测量每一列和每一行的大小来重新计算DataGrid的大小,可能是通过填充整个网格(据我所知),它本应以某种方式明智地处理这一问题,但在本案中,情况并非如此

要快速检查这是否是相关问题,请在测试期间将DataGrid的
高度
宽度
属性设置为固定大小,然后再次尝试运行。如果性能恢复,以下选项中可能会有永久性修复:

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

在我的例子中,我遇到了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>
<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>
<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>

加载时间21秒:

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

加载时间16秒:

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

我有一个Surface Pro 3,上面有大约200行10列的datagrid,滚动速度非常慢,而且不稳定而且犹豫

我以为是网络,但事实上是图形卡无法跟上——等等——数据网格本身的阴影效果,即使控件的背景设置为纯色

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

希望这有帮助。

我在谷歌上找到了一种解决方案。正如作者所说,我禁用了GroupStyle,渲染速度问题得到了解决。但我需要分组。作者说

VirtualizingPanel.IsVirtualizingWhenGrouping
添加到.NET 4.5中。因此我将其设置为true。现在,分组可以快速渲染。问题是…滚动是不稳定的。不是不可接受的不稳定,而是明显的不稳定。当我尝试创建一个扩展了2000多个节点的树视图时,我遇到了类似的问题。没有虚拟化,渲染很慢,但滚动很平滑。有了虚拟化,rendering很快,但滚动很快


为什么我们不能两者都有…

我对绑定数据网格也有同样的问题,我注意到在第一次加载时它很快,但在第二次加载时它很慢

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

对我来说它是:

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


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

好吧,再添加一点(我知道这是一个非常古老的主题,但它仍然对某些人有帮助)

我试过了

EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True" 
对于DataGrid(
AutoGenerateColumns=“True”
)绑定到DataTable.DefaultView()并且对速度没有影响,这对于速度以及行之间的导航来说仍然是可怕的。然后,我提出了设置DataGrid的固定高度和宽度的解决方案。此外,我还设置了

RowHeight="23" 
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
这使得我的页面填充速度非常快…现在几乎不需要10-12秒,而不是2分钟

希望它能帮助别人


注意:我使用的是.Net 4.5,在渲染时间为7-10秒的情况下,我遇到了1000行5列的大问题,但在上找到的解决方案立即加载了网格

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

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


如果您有如下行定义:

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