WPF 数据网格性能

     2023-02-22     170

关键词:

【中文标题】WPF 数据网格性能【英文标题】:WPF Datagrid Performance 【发布时间】:2010-10-16 09:51:23 【问题描述】:

我正在使用 WPF Toolkit 数据网格,目前它的滚动速度非常慢。网格有 84 列和 805 行。 (包括 3 个固定列和标题是固定的。)水平和垂直滚动都非常慢。虚拟化已打开,我已在 xaml 中显式启用列虚拟化和行虚拟化。有什么需要注意的会真正影响性能,例如绑定方法,或者每个单元格模板中的 xaml 是什么?

需要注意的一点是,我在创建数据网格时动态添加列。那会影响什么吗? (我还同时动态创建单元格模板,以便我的绑定设置正确。)

以下是生成的大多数单元格的模板代码。基本上对于我需要动态添加的列(其中大部分),我遍历我的列表并使用 AddColumn 方法添加列,另外我动态构建模板以便绑定语句正确索引集合中的正确项目对于该列。模板不太复杂,只有两个 TextBlock,但我确实在每个上绑定了四个不同的属性。通过将绑定更改为 OneWay,我似乎能够挤出更多性能:

 private void AddColumn(string s, int index)
    
        DataGridTemplateColumn column = new DataGridTemplateColumn();
        column.Header = s;
        //Set template for inner cell's two rectangles
        column.CellTemplate = CreateFactViewModelTemplate(index);
        //Set Style for header, ie rotate 90 degrees
        column.HeaderStyle = (Style)dgMatrix.Resources["HeaderRotateStyle"];
        column.Width = DataGridLength.Auto;
        dgMatrix.Columns.Add(column);
    


    //this method builds the template for each column in order to properly bind the rectangles to their color
    private static DataTemplate CreateFactViewModelTemplate(int index)
    
        string xamlTemplateFormat =
            @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
            <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column=""0"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""Binding Path=FactViewModels[~Index~].LeftForeColor,Mode=OneWay"" Background=""Binding Path=FactViewModels[~Index~].LeftColor,Mode=OneWay"" Text=""Binding Path=FactViewModels[~Index~].LeftScore,Mode=OneWay"" />
            <TextBlock Grid.Column=""1"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""Binding Path=FactViewModels[~Index~].RightForeColor,Mode=OneWay"" Background=""Binding Path=FactViewModels[~Index~].RightColor,Mode=OneWay"" Text=""Binding Path=FactViewModels[~Index~].RightScore,Mode=OneWay"" />
            </Grid>
            </DataTemplate>";




        string xamlTemplate = xamlTemplateFormat.Replace("~Index~", index.ToString());

        return (DataTemplate)XamlReader.Parse(xamlTemplate);
    

【问题讨论】:

是的,Microsoft Excel 甚至比最快的商业 WPF 数据网格控件快 100 倍。数据网格确实突出了 WPF 的弱点。 15 年前的 Delphi 数据网格在 15 年前的硬件上运行得更快。 【参考方案1】:

由于我看不到您的源代码,因此很难为您提供帮助。特别是因为 WPF 应用程序的性能受到很多因素的影响。有关注意事项的一些提示,请参阅Optimizing WPF Application Performance。是的 - 每个单元格中使用什么 xaml 非常重要。因为通常性能问题归结为“元素太多”。你知道我认为一个 TextBox 是 30 个单独的元素吗?我建议您使用Performance Profiling Tools for WPF 来了解有关您的具体问题的更多信息。尽量减少使用的元素数量(例如,在适当的情况下从 TextBox 切换到 TextBlock)。

此外,您还必须检查在您试用该应用程序的任何 PC 上是否存在性能问题。也许您正在使用的 PC 迫使 WPF 进入基于软件的渲染。或者您是否在使用任何 BitmapEffects?

编辑: 查看您的代码,我建议您更改

column.Width = DataGridLength.Auto;

到一个合理的固定宽度,因为数据网格不必在每次发生变化(如添加行,甚至滚动)时动态地​​重新计算宽度。

【讨论】:

使用.net 4.0 DataGrid(以前的工具包之一),我有同样该死的问题,我只使用DataGridTextBoxColumns。我有更少的行(20,这意味着行虚拟化在我的情况下是无用的),但是 100 列(这里虚拟化有很大的不同,但是每次水平滚动时仍然需要大约 2 秒来显示网格和刷新 1 秒.. .)。将 bindingMode 设置为 oneWay 对我来说根本没有任何区别:(。仍在试图找出一种让事情变得更快的方法,但据我所知,这是整个 DG 创建细胞的速度非常慢。 .【参考方案2】:

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

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

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

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

【讨论】:

将 DataGrid.Height 设置为固定值解决了我的问题。谢谢! 设置 DataGrid.MaxHeight 也有帮助。【参考方案3】:

在我的一个项目中,以下网格样式设置导致了主要的性能问题:

 <Style  TargetType='x:Type controls:DataGrid'>
    <Setter Property='ScrollViewer.CanContentScroll' Value='False' />
    ...

当我删除 ScrollViewer.CanContentScroll 设置后,性能问题就消失了。

【讨论】:

你是我的英雄。我搜索了这个问题很长时间。这就是解决方案。用户界面立即响应仅删除此行... 您可以将其添加到样式中(如答案所述)。或者您可以将其添加到您的数据网格中:【参考方案4】:

您是否安装了任何类型的平板电脑(通过 USB 或平板电脑)?

我在使用平板电脑时在 WPF 数据网格中发现了一个性能错误。我发布了一个视频,得到了 MS here in this thread

的认可

干杯, 乔恩

【讨论】:

不幸的是 WPF 的 DataGrid 速度非常慢,没有任何与平板电脑相关的错误。 我在一个关键任务实时应用程序中使用它(大概有 20-30 个实例,每个网格有 2K-3K 条记录),它对我们来说很快。 好吧,问题是有很多 WinForms/native 解决方案可以毫不费力地处理 100K 行/20 列。 DataGrid 就没那么幸运了。 是的...从未尝试过 100K 行...但我的行在上述规格中有图标、渐变等。只是一个参考点...【参考方案5】:

我有一个案例,我的底层对象只有 setter 的属性。通过在集合中实现 ITypedList 并通过单个对象上的 TypeDescriptionProvider/ICustomTypeDescriptor 可以访问相同的属性。删除属性或添加 getter 解决了性能问题。

【讨论】:

【参考方案6】:

在这种情况下,我建议的一件事是查看您如何应用样式以及每个单元格上的样式。 如果它具有复杂的视觉树,则应用的样式确实会降低性能。

您也可以在最新的 WPF Datagrid 上尝试延迟滚动选项。

【讨论】:

将 ObservableCollection 绑定到 wpf 数据网格:网格保持为空

】将ObservableCollection绑定到wpf数据网格:网格保持为空【英文标题】:BindanObservableCollectiontoawpfdatagrid:Gridstaysempty【发布时间】:2013-02-1118:52:56【问题描述】:我想将ObservableCollection绑定到wpf数据网格。我的ObservableCollection不为空... 查看详情

如何将选定的行从一个 wpf 数据网格复制到另一个 wpf 数据网格? [关闭]

】如何将选定的行从一个wpf数据网格复制到另一个wpf数据网格?[关闭]【英文标题】:howtocopyselectedrowsfromonewpfdatagridtoanotherwpfdatagrid?[closed]【发布时间】:2016-04-1621:30:28【问题描述】:将行从一个WPFdatagrid1复制到另一个wpfdatagrid2... 查看详情

WPF 数据网格 |隐藏行验证列

】WPF数据网格|隐藏行验证列【英文标题】:WPFDataGrid|HidingRowValidationColumn【发布时间】:2013-04-1907:29:23【问题描述】:我有一个WPF数据网格,它有4列,所有这些都是数据网格模板列。当网格呈现时,左侧会自动添加一列,据我了... 查看详情

WPF数据网格粘贴

】WPF数据网格粘贴【英文标题】:WPFdatagridpasting【发布时间】:2011-05-0608:09:15【问题描述】:我无法从csv粘贴到wpf数据网格中-我已按照此处的建议进行操作Link并且代码执行没有问题-但是,似乎所有新行都已创建,但只有第一行... 查看详情

WPF数据网格左栏

】WPF数据网格左栏【英文标题】:WPFdatagridleftcolumn【发布时间】:2012-09-1923:52:01【问题描述】:当我在WPF中创建数据网格时,左侧有一列很薄。我不知道它的目的是什么。也许它是一个状态列?如何禁用它?【问题讨论】:见How... 查看详情

样式化 wpf 数据网格

】样式化wpf数据网格【英文标题】:Styleawpfdatagrid【发布时间】:2012-09-1418:15:19【问题描述】:我找到了wpf的示例样式,如下所示,它所做的主要工作是更改DataGridColumnHeader的背景颜色并仍然保留排序箭头。可以看出,排序箭头... 查看详情

如何重新加载 WPF 网格

...mycode我正在开发一个WPF应用程序来在单击更新按钮时更新数据库。我还想在单击更新按钮后将我从数据库获取的数据重新加载到网格中...请帮助我解决这个问题【问题讨论】:HowtorefreshdatagridinWPF的可能重复我在问网格。不是数... 查看详情

数据网格行标题 WPF

】数据网格行标题WPF【英文标题】:DataGridRowHeaderWPF【发布时间】:2016-05-1904:55:03【问题描述】:我有一个包含7个已定义列的填充数据表(xDataTable)-我想用作我的RowHeader的第一列。我也有一个DataGrid:<DataGridx:Name="DataGridX"ItemsSour... 查看详情

获取数据网格列值 - WPF C#

】获取数据网格列值-WPFC#【英文标题】:Getdatagridcolumnvalue-WPFC#【发布时间】:2017-11-1621:26:53【问题描述】:我有一个包含两列的数据网格;好和修井。WPF:<DataGridx:Name="PrintReport1"ItemsSource="BindingTableResults"AutoGenerateColumns="False"Fo... 查看详情

如何在 WPF 数据网格上自动滚动

】如何在WPF数据网格上自动滚动【英文标题】:HowtoautoscrollonWPFdatagrid【发布时间】:2010-11-0420:26:08【问题描述】:我觉得我很傻。我现在搜索了15分钟,发现了几种不同的在数据网格上滚动的解决方案,但似乎没有一个适合我。... 查看详情

内存映射文件到 WPF 网格

...理一个大文件(8GB)。我希望能够将内容放入WPF网格(例如数据网格)中,但我遇到了麻烦,因为每种似乎可行的方法都必须将文件加载到内存中,这破坏了内存映射文件的要点.我知道wpf数据网格只能访问所需的数据,但我如何将 查看详情

将数据表绑定到 WPF 数据网格

】将数据表绑定到WPF数据网格【英文标题】:IssuebindingdatatabletoWPFdatagrid【发布时间】:2017-05-1421:12:25【问题描述】:我的XAML如下:<DataGridx:Name="WaterfallDataGrid"HorizontalAlignment="Left"Height="540"Margin="10,410,0,0"VerticalAlignment="Top"Width 查看详情

冻结wpf数据网格中的列

】冻结wpf数据网格中的列【英文标题】:Freezingcolumnsinwpfdatagrid【发布时间】:2010-12-2507:33:29【问题描述】:我有一些表格数据,其中包含很多字段,当我的WPF应用程序调整大小时,其中很多都被切断了。但是,我希望始终看到... 查看详情

WPF 中的数据网格绑定

】WPF中的数据网格绑定【英文标题】:DatagridbindinginWPF【发布时间】:2011-08-1404:01:09【问题描述】:我知道这已经被问过了,但我已经做了开发人员建议的几乎所有事情。<DataGridx:Name="Imported"VerticalAlignment="Top"DataContext="BindingSour... 查看详情

带有自定义列的 WPF 数据网格绑定

】带有自定义列的WPF数据网格绑定【英文标题】:WPFdatagridbindingwithcustomcolumns【发布时间】:2013-08-1116:55:03【问题描述】:目前我正在开发WPF应用程序(使用MVVM),其中我在DataGridView中显示数据。<DataGridRowHeaderWidth="0"ItemsSource=... 查看详情

使用 WPF 数据网格更新 SQL 数据库表

】使用WPF数据网格更新SQL数据库表【英文标题】:UpdatingSQLdatabasetableusingWPFdatagrid【发布时间】:2017-11-0608:50:37【问题描述】:我是WPF新手,我正在尝试让数据网格在用户编辑本地SQL数据库中的表时自动更新它。我觉得我已经接... 查看详情

WPF 数据网格样式

】WPF数据网格样式【英文标题】:WPFDataGridStyling【发布时间】:2010-10-0710:55:01【问题描述】:是否有人知道/有一个示例,说明如何将WPFDataGrid布局更改为卡片视图或其他任何东西,而不仅仅是行堆栈?【问题讨论】:你能给我们... 查看详情

将 Wpf 的数据网格绑定到数据库

】将Wpf的数据网格绑定到数据库【英文标题】:bindingdatagridforWpftoaDB【发布时间】:2012-11-2100:34:00【问题描述】:我正在尝试将WPF的DataGrid绑定到MSSQL数据库中的表。1)首先我创建了一个App.config文件如下rrr<connectionStrings><ad... 查看详情