DataGridView 在我的两个屏幕之一上的可怕重绘性能 [英] Horrible redraw performance of the DataGridView on one of my two screens
问题描述
我的双显示器系统上的 DataGridView 遇到了一个非常奇怪的问题.该问题表现为控件的重绘极其缓慢(完全重绘需要 30 秒),但仅当它出现在我的一个屏幕上时.另一方面,重绘速度很好.
I ran into a very odd issue with the DataGridView on my dual-monitor system. The issue manifests itself as an EXTREMELY slow repaint of the control (like 30 seconds for a full repaint), but only when it is on one of my screens. When on the other, the repaint speed is fine.
我有一台 Nvidia 8800 GT 和最新的非测试版驱动程序(175.某事).是驱动程序错误吗?我将把它搁置一旁,因为我必须忍受这种特殊的配置.(不过,它不会发生在 ATI 卡上...)
I have an Nvidia 8800 GT with the latest non-beta drivers (175. something). Is it a driver bug? I'll leave that up in the air, since I have to live with this particular configuration. (It does not happen on ATI cards, though...)
绘制速度与单元格内容无关,自定义绘制根本不会提高性能 - 即使只是绘制实心矩形.
The paint speed has nothing to do with the cell contents, and custom drawing doesn't improve the performance at all - even when just painting a solid rectangle.
我后来发现在表单上放置一个 ElementHost(来自 System.Windows.Forms.Integration 命名空间)可以解决这个问题.它不必被搞乱;它只需要是 DataGridView 所在表单的子项.只要 Visible 属性为真,就可以将其大小调整为 (0, 0).
I later find out that placing a ElementHost (from the System.Windows.Forms.Integration namespace) on the form corrects the problem. It doesn't have to be messed with; it just needs to be a child of the form the DataGridView is also on. It can be resized to (0, 0) as long as the Visible property is true.
我不想将 .NET 3/3.5 依赖项显式添加到我的应用程序中;我使用反射创建了一种在运行时(如果可以)创建此控件的方法.它可以工作,至少它在没有所需库的机器上正常失败 - 它只是恢复缓慢.
I don't want to explicitly add the .NET 3/3.5 dependency to my application; I make a method to create this control at runtime (if it can) using reflection. It works, and at least it fails gracefully on machines that don't have the required library - it just goes back to being slow.
此方法还允许我在应用程序运行时申请修复,从而更容易查看 WPF 库在我的表单上发生的变化(使用 Spy++).
This method also lets me apply to fix while the app is running, making it easier to see what the WPF libraries are changing on my form (using Spy++).
经过大量试验和错误后,我注意到在控件本身(而不是仅表单)上启用双缓冲可以解决问题!
After a lot of trial and error, I notice that enabling double buffering on the control itself (as opposed to just the form) corrects the issue!
因此,您只需要基于 DataGridView 创建一个自定义类,以便启用它的 DoubleBuffering.就这样!
So, you just need to make a custom class based off of DataGridView so you can enable its DoubleBuffering. That's it!
class CustomDataGridView: DataGridView
{
public CustomDataGridView()
{
DoubleBuffered = true;
}
}
只要我所有的网格实例都使用这个自定义版本,一切都很好.如果我遇到由此导致的情况,我无法使用子类解决方案(如果我没有代码),我想我可以尝试将该控件注入表单 :) (尽管我更有可能尝试使用反射从外部强制启用 DoubleBuffered 属性,以再次避免依赖).
As long as all of my instances of the grid are using this custom version, all is well. If I ever run into a situation caused by this where I'm not able to use the subclass solution (if I don't have the code), I suppose I could try to inject that control onto the form :) (although I'll be more likely to try using reflection to force the DoubleBuffered property on from the outside to once again avoid the dependency).
很遗憾,这么简单的事情占用了我这么多时间......
It is sad that such a trivially simple thing ate up so much of my time...
推荐答案
您只需要基于 DataGridView 创建一个自定义类,以便启用它的 DoubleBuffering.就这样!
You just need to make a custom class based off of DataGridView so you can enable its DoubleBuffering. That's it!
class CustomDataGridView: DataGridView
{
public CustomDataGridView()
{
DoubleBuffered = true;
}
}
只要我所有的网格实例都使用这个自定义版本,一切都很好.如果我遇到因此无法使用子类解决方案(如果我没有代码)的情况,我想我可以尝试将该控件注入表单:)(尽管我将更有可能尝试使用反射从外部强制启用 DoubleBuffered 属性,以再次避免依赖).
As long as all of my instances of the grid are using this custom version, all is well. If I ever run into a situation caused by this where I'm not able to use the subclass solution (if I don't have the code), I suppose I could try to inject that control onto the form :) (although I'll be more likely to try using reflection to force the DoubleBuffered property on from the outside to once again avoid the dependency).
很遗憾,这么简单的事情占用了我这么多时间......
It is sad that such a trivially simple thing ate up so much of my time...
注意:将答案设为答案,以便将问题标记为已回答
Note: Making the answer an answer so the question can be marked as answered
这篇关于DataGridView 在我的两个屏幕之一上的可怕重绘性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!