【问题标题】:DataGrid slow to RedrawDataGrid 重绘速度慢
【发布时间】:2009-05-09 00:15:17
【问题描述】:

我正在使用 System.Windows.Forms.DataGrid。它填充了大约 3000 行,并且重绘非常缓慢。如果我最小化和最大化我的表单,所有其他控件只会显示,但我最终会看到 DataGrid 逐行重绘。此 DataGrid 中的所有内容都是只读的(如果有影响)。

更新:

我不确定如何为我的项目正确实施 CellValueNeeded() 事件,或者它是否有助于提高我的 DataGrid 的性能。

我正在创建一个包含 DataGridView 的用户控件(请参见下面的代码)。当调用 SetProject() 方法时,我的控件设置为我的 Project 类的特定实例。然后控件使用静态方法 Informa.Data.GetProjectDataTable(Project proj) 从 Project 中提取 DataTable。然后将 DataGrid 的 DataSource 属性设置为返回的 DataTable。

这是我第一次使用 ADO 或 DataGrids 做任何事情,所以请耐心等待。看起来 CellValueNeed() 允许我覆盖 DataGrid 如何为其中一个单元格查找值,但在我的情况下,这比 MSDN 上的示例复杂得多。我的数据的实际来源是各种 Node 对象的树形结构,其根是 Project 实例。每个节点都可以有一组可变的属性,用户也可以在运行时对其进行扩展。然后还有许多其他复杂性,节点从其父节点继承属性值,并从其子节点汇总其他属性。

Informa.Data.GetProjectDataTable() 消除了所有这些疯狂并生成所有节点的所有属性的单个平面数据表。在这一点上,我不关心能够将此表的任何更改与原始树结构相关联,或者在树结构更改时更新表的特定部分。我要做的就是在 DataGrid 中向用户显示数据。

那么我是否实现 CellValueNeeded() 以从项目提供的 DataTable 中读取?我认为 DataGrid 已经知道如何高效地将 DataTable 用作 DataSource?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Informa;

namespace Informa
{
public partial class ProjectGridControl : UserControl
{
    private Project proj;

    public ProjectGridControl()
    {
        InitializeComponent();
    }

    public void SetProject(Project proj)
    {
        this.proj = proj;
        UpdateGridControl();
    }

    public void UpdateGridControl()
    {
        if (this.proj == null)
        {
            this.dataGrid.DataSource = null;
        }
        else
        {
            //Extracts a DataTable from the project and sets it as the 
            //DataSource of the property grid
            this.dataGrid.DataSource = Informa.Data.GetProjectDataTable(proj);
        }
    }
}

}

【问题讨论】:

  • 建议您发布一些(缩减的)代码...
  • 触发了什么事件?你在处理什么事件?如果您在绑定的每个列/行/单元格上运行代码,我会在那里检查。
  • 我没有处理任何事件。我正在创建一个 DataTable 并将其设置为 DataGrid 的 DataSource。就是这样。

标签: c# datagrid


【解决方案1】:

曾经有一只名叫 MacroSoft 的小狼,它和 Vidia the Sheep 一起度过了一段时间。他们制作了地球上最慢的文本和网格渲染,并在硬件发展繁荣的一年将所有工作推到了 CPU 上;一直以来,绵羊确保进一步放慢速度。

如果我是对的,那你欠他一封信 :-)

您正在运行 NVidia 卡及其糟糕的驱动程序或类似设备,并且看到 MSFT 拒绝与友好的供应商一起将 GDI+ 修复为硬件加速(即使 Mono 会在他们决定为您提供一些节能和适当的硬件之前完成它重用;你知道体面的工程)。

将您的 DataGridView 包装成一个新类型(即继承)并将其 DoubleBuffered 属性设置为 true,更改设计器代码以使用该新类型。

可见的“逐行”渲染是这个行业在 2009/2010 年的糟糕程度.小丑..

【讨论】:

  • 是的,将双缓冲设置为 true 似乎已经修复了它。谢谢。
  • 类 DBDataGridView : System.Windows.Forms.DataGridView { public DBDataGridView() { DoubleBuffered = true; } }
  • 我正在使用 bindingsource 填充 Datagridview。我有大约 1000 条记录。我使用了 DoubleBuffered 属性并将其设置为 true。我还是很慢。
【解决方案2】:

您是否启用了列的自动调整大小?由于启用了自动调整大小,我让用户在我们的应用程序中遇到了只有 10 行的大幅减速。基本上,一个网格允许用户选中/取消选中一个框以将一行添加到另一个网格,而第二个网格会随着每添加一行而出现指数级减速。

经过一些分析,我发现将 5 行添加到第二个表大约需要 12 秒。最后尝试关闭列的自动调整大小,现在是即时的。

【讨论】:

  • 没有自动调整行和列的大小。不过感谢您的建议。
  • @Chris Doggett:谢谢,谢谢,谢谢!!!经过1.5小时的调试,终于找到了你的帖子。现在选择一行的运行速度提高了大约 500% ;-)
  • 嗨。我可以知道如何关闭AutoSize 吗?找不到任何文件。谢谢。
  • 精彩的观察!有趣的是,这会产生如此大的不同。
【解决方案3】:

我在绘制 datagridview 时遇到了很大的麻烦。我需要我的屏幕尽可能大,而且它的物理尺寸对疼痛速度的影响似乎比数据量等要大得多。对我来说真正的诀窍是设置 CellBorderStyle=None (显然每个单元格都负责绘制自己的边框,这似乎很荒谬,因为单元格边框保持固定在屏幕上,所以每个单元格在滚动时都不需要不断地重新绘制自己的边框,但无论如何......)。

现在,没有单元格边框的网格并不是一个好的网格。但幸运的是,您可以为列和行设置 DividerWidth。这些值默认为 0,但将它们设置为 1(如果您想要更厚,则设置为更高)将使您的“单元”边框在外观上与 CellBorderStyle=Single 相同,但这次是“静态”绘制的(因为没有更好的词) 用于整个数据网格视图。

此外,如果您有很多行,请将 AutoResize 属性设置为 False。

至少在我的情况下,绘画速度的提高是巨大的。

【讨论】:

  • 伟大的观察!我打开了虚拟模式,但没有任何帮助(我有 20x7 网格,每 20 毫秒通过计时器进行 3 次更新)。但是这个大大提高了性能。
  • 如果您尝试过 DoubleBuffered 解决方案,您是否需要此解决方案?
【解决方案4】:

DataGridView 应该可以处理 3000 行,在虚拟模式下没有问题。

确保将VirtualMode 设置为true(您提到您尝试过此操作),并正确实现CellValueNeeded

阅读MSDN Walkthrough on VirtualMode了解详情。

【讨论】:

    【解决方案5】:

    在 Visual Studio 2015 中,将 2 个 DataGridView AutoSize 列设置为无

    dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
    

    导致行添加和用户列大小调整非常缓慢的问题。

    因此,如果我 REM 退出上述行,则用户体验现在很快。请参阅AutoSizeRowsModeAutoSizeColumnsMode 可能是相同的问题

    【讨论】:

      猜你喜欢
      • 2011-11-11
      • 2018-08-08
      • 2011-10-04
      • 2017-06-25
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 2019-05-09
      相关资源
      最近更新 更多