如何提高DataGridView的绘画性能?

时间:2021-09-19 03:20:02

(sorry for bad English)

(抱歉英文不好)

I have a big problem with performance of DataGridView when it re-paints.

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

I'm using a DataGridView to show logs from an external application stream. Messages from the stream come in with a high frequency (less than 1 ms). If I add new row to the DataGridView immediately when each new message comes, the DataGridView doesn't have time to re-paint itself before the next message comes.

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

A possible solution is to use a queue to collect messages and re-paint DataGridView every 100 ms with messages from queue. This is good but the DataGridView blinks when it auto-scrolls to the last row. (Smooth scroll is disabled)

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

Can you help me to improve DataGridView performance?

你能帮助我提高DataGridView的性能吗?

6 个解决方案

#1


41  

I recently had some slowness issues with DataGridView and the solution was the following code

我最近对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);
}

It turns double buffering on for DataGridView objects. Just call DoubleBuffered() on your DGV. Hope it helps.

它为DataGridView对象打开了双缓冲。只需在您的DGV上调用DoubleBuffered()即可。希望能帮助到你。

Edit: I might've gotten this off SO, but I can't search for the original right now so this is just to emphasize that the code isn't mine.

编辑:我可能已经把它关闭了,但我现在无法搜索原文,所以这只是为了强调代码不是我的。

#2


9  

Have you enabled double buffering for the grid view?

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

have a look at Horrible redraw performance of the DataGridView on one of my two screens

看看我的两个屏幕之一的DataGridView的可怕重绘性能

if you haven't already for some ideas

如果你还没有一些想法

#3


4  

Clean Solution without reflection is:

没有反射的清洁溶液是:

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

Then go to myForm.designer.cs and change a type from DataGridView to DataGridViewDoubleBuffered .

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

#4


3  

Also read MSDN article: Best Practices for Scaling the Windows Forms DataGridView Control

另请阅读MSDN文章:扩展Windows窗体DataGridView控件的最佳实践

#5


3  

When working with large amounts of data, the DataGridView control can consume a large amount of memory in overhead, unless you use it carefully. On clients with limited memory, you can avoid some of this overhead by avoiding features that have a high memory cost.

使用大量数据时,DataGridView控件可能会消耗大量内存,除非您仔细使用它。在内存有限的客户端上,您可以通过避免具有高内存成本的功能来避免一些此类开销。

You can also manage some or all of the data maintenance and retrieval tasks yourself using virtual mode in order to customize the memory usage for your scenario. More detail you can visit dapfor. com

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

#6


3  

i use this solution and saw bit fixed.

我使用这个解决方案,看到有点固定。

Reflection is used so import this too in code

使用反射,因此在代码中也导入它

using System.Reflection;

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

#1


41  

I recently had some slowness issues with DataGridView and the solution was the following code

我最近对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);
}

It turns double buffering on for DataGridView objects. Just call DoubleBuffered() on your DGV. Hope it helps.

它为DataGridView对象打开了双缓冲。只需在您的DGV上调用DoubleBuffered()即可。希望能帮助到你。

Edit: I might've gotten this off SO, but I can't search for the original right now so this is just to emphasize that the code isn't mine.

编辑:我可能已经把它关闭了,但我现在无法搜索原文,所以这只是为了强调代码不是我的。

#2


9  

Have you enabled double buffering for the grid view?

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

have a look at Horrible redraw performance of the DataGridView on one of my two screens

看看我的两个屏幕之一的DataGridView的可怕重绘性能

if you haven't already for some ideas

如果你还没有一些想法

#3


4  

Clean Solution without reflection is:

没有反射的清洁溶液是:

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

Then go to myForm.designer.cs and change a type from DataGridView to DataGridViewDoubleBuffered .

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

#4


3  

Also read MSDN article: Best Practices for Scaling the Windows Forms DataGridView Control

另请阅读MSDN文章:扩展Windows窗体DataGridView控件的最佳实践

#5


3  

When working with large amounts of data, the DataGridView control can consume a large amount of memory in overhead, unless you use it carefully. On clients with limited memory, you can avoid some of this overhead by avoiding features that have a high memory cost.

使用大量数据时,DataGridView控件可能会消耗大量内存,除非您仔细使用它。在内存有限的客户端上,您可以通过避免具有高内存成本的功能来避免一些此类开销。

You can also manage some or all of the data maintenance and retrieval tasks yourself using virtual mode in order to customize the memory usage for your scenario. More detail you can visit dapfor. com

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

#6


3  

i use this solution and saw bit fixed.

我使用这个解决方案,看到有点固定。

Reflection is used so import this too in code

使用反射,因此在代码中也导入它

using System.Reflection;

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