【问题标题】:How to improve painting performance of DataGridView?如何提高 DataGridView 的绘制性能?
【发布时间】:2011-05-14 09:34:23
【问题描述】:

(抱歉英语不好)

DataGridView 重新绘制时的性能存在问题。

我正在使用DataGridView 来显示来自外部应用程序流的日志。来自流的消息以高频率(小于 1 毫秒)进入。如果我在每条新消息到来时立即向DataGridView 添加新行,则DataGridView 在下一条消息到来之前没有时间重新绘制自己。

一种可能的解决方案是使用队列来收集消息,然后每 100 毫秒使用队列中的消息重新绘制 DataGridView。这很好,但DataGridView 在自动滚动到最后一行时会闪烁。 (平滑滚动被禁用)

您能帮我提高DataGridView 的性能吗?

【问题讨论】:

标签: .net winforms datagridview repaint paint


【解决方案1】:

我最近遇到了DataGridView 的一些缓慢问题,解决方案是以下代码

public static void DoubleBuffered(this DataGridView dgv, bool setting)
{
    Type dgvType = dgv.GetType();
    PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
          BindingFlags.Instance | BindingFlags.NonPublic);
    pi.SetValue(dgv, setting, null);
}

它为DataGridView 对象打开双缓冲。只需在您的 DGV 上致电 DoubleBuffered()。希望对您有所帮助。

编辑:我可能已经从 SO 中得到了这个,但我现在无法搜索原件,所以这只是为了强调代码不是我的。

【讨论】:

  • 您发布的方法使用反射来更改DataGridView 控件上的非公共属性。这是一个可接受的解决方案,但仅继承现有的DataGridView 控件并使用“DoubleBuffered”样式集创建您自己的自定义控件可能更简洁。
  • 我的问题是,如果我派生出我自己的控件,那么编辑器中的表单将不会显示。
【解决方案2】:

您是否为网格视图启用了双缓冲?

看看 Horrible redraw performance of the DataGridView on one of my two screens

如果您还没有一些想法

【讨论】:

    【解决方案3】:

    没有反射的干净解决方案是:

    public class DataGridViewDoubleBuffered : DataGridView
    {
       public DataGridViewDoubleBuffered()
       {
           DoubleBuffered = true;
       }
    }
    

    然后转到 myForm.designer.cs 并将类型从 DataGridView 更改为 DataGridViewDoubleBuffered 。

    【讨论】:

    • 如果您在解决方案资源管理器中展开 MyForm.cs,您可以打开 MyForm.Designer.cs 并使其实例化双缓冲子类而不是基类。
    • 感谢您的支持 - 白天和黑夜不同。对于任何想知道如何做到这一点的人——将这个类添加到代码的底部——我将它添加到我的表单类之外的命名空间中。然后,打开表单的Designer.CS (Form1.Designer.cs) 并单击Windows Form Designer generated code 旁边的+ 符号以取消隐藏该部分。更改 datagridview 初始化(类似于 this.dataGridView1 = new System.Windows.Forms.DataGridView) - 将其更改为 this.dataGridView1 = new DataGridViewDoubleBuffered。然后,向下滚动到它的声明底部。
    • 将声明 (private System.Windows.Forms.DataGridView dataGridView1) 更改为 private DataGridViewDoubleBuffered dataGridView1。我还继续对我的表单进行双缓冲 - 可能值得做 - 不确定是否有必要。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      处理大量数据时,DataGridView 控件会消耗大量内存开销,除非您小心使用它。在内存有限的客户端上,您可以通过避免具有高内存成本的功能来避免部分开销。

      您还可以使用虚拟模式自行管理部分或全部数据维护和检索任务,以便为您的场景自定义内存使用情况。更多细节你可以访问 dapfor。 com

      【讨论】:

        【解决方案6】:

        我使用了这个解决方案并且看到了一些固定的东西。

        使用了反射,所以在代码中也导入它

        using System.Reflection;
        
        typeof(DataGridView).InvokeMember("DoubleBuffered",
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
        null,this.dataGridView1,new object[] { true });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-24
          • 2023-04-03
          • 2020-02-17
          • 2012-05-01
          • 2015-03-12
          • 1970-01-01
          • 2019-08-23
          相关资源
          最近更新 更多