We had a performance issue with DataGridViews where the redraw was horridly slow and found the solution Here to create a derived type and enable double buffering on the control. (Derived type is necessary since the DoubleBuffered property is protected)
我们在DataGridViews中遇到了性能问题,其中重绘速度非常慢并且找到了解决方案这里创建派生类型并在控件上启用双缓冲。 (由于DoubleBuffered属性受到保护,因此派生类型是必需的)
It doesn't seem like there's any drawback to having the DoubleBuffered property set to true.
将DoubleBuffered属性设置为true似乎没有任何缺点。
4 个解决方案
#1
16
It is protected because DGV inherits the property from Control. And Control.DoubleBuffered is protected. Which makes sense because each derived control should decide for itself to turn that on. And it doesn't make sense for the control user to arbitrarily turn it on or off. The DGV designers decided for off.
它受到保护,因为DGV从Control继承了该属性。并且Control.DoubleBuffered受到保护。这是有道理的,因为每个派生控件都应该决定自己打开它。控制用户随意打开或关闭它是没有意义的。 DGV设计师决定关闭。
One reason they might have decided that is that double buffering actually makes painting slower. The extra step to render the buffer bitmap costs time. It just looks faster to the human eye, you observe the bitmap suddenly appearing. You can't see the time it takes to draw into the bitmap. Unless other controls need to be painted and they get their turn after the DGV, then it is quite visible.
他们可能已经决定的一个原因是双缓冲实际上使绘画变慢。渲染缓冲区位图的额外步骤需要花费时间。只是人眼看起来更快,你会看到突然出现的位图。您无法看到绘制位图所需的时间。除非需要绘制其他控件并且他们在DGV之后轮到他们,否则它是非常明显的。
What you see is the form getting drawn first, with holes where the controls go. Those holes have a white background. Black when you use the TransparencyKey or Opacity property. Each control then gets the Paint event and the holes are filled one-by-one. That effect is perceived as flicker too by the user, although it is a different kind of flicker from the one that DoubleBuffered solves. It is especially noticeable when the background is black.
您看到的是首先绘制的表单,其中包含控件所在的孔。那些洞有白色背景。使用TransparencyKey或Opacity属性时为黑色。然后每个控件获取Paint事件,并逐个填充孔。这种效果被用户感知为闪烁,尽管它与DoubleBuffered解决的闪烁不同。当背景为黑色时尤其明显。
What's needed to solve this problem is that the entire form, with all its controls, is double-buffered. That's not available in Windows Forms. However, Windows XP and later actually support this. Check this thread to see how that's done. Beware that it can have side-effects as documented in that thread.
解决这个问题需要的是整个表单及其所有控件都是双缓冲的。这在Windows窗体中不可用。但是,Windows XP及更高版本实际上支持这一点。检查这个帖子,看看是怎么做的。请注意,它可能具有该线程中记录的副作用。
#2
12
I think its best solution:
我认为它的最佳解决方案:
typeof(DataGridView).InvokeMember(
"DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null,
myDataGridViewObject,
new object[] { true });
found here
#3
4
Inheritance is not needed to turn on doublebuffering on a datagridview. You can do it with reflection on an existing datagridview.
在datagridview上启用doublebuffering不需要继承。您可以使用现有datagridview上的反射来完成此操作。
#4
2
Double buffering by definition uses two buffers and twice the memory for rendering the view of the control into. So, there is some drawback there, however, with the amount of memory you get in a PC now, not many people probably would notice the sacrifice.
根据定义,双缓冲使用两个缓冲区和两倍的内存来渲染控件的视图。因此,有一些缺点,然而,现在你在PC中获得的内存量,并不是很多人可能会注意到牺牲。
No idea why its protected. Maybe the function wasn't available in an early version of the control, and when it was introduced the designers didn't want to change the public interface of the control. Or perhaps they considered it to be an advanced feature and wanted to limit the number of methods someone new to the control would have to grok to be able to make it do something useful.
不知道为什么它受到保护。也许该功能在早期版本的控件中不可用,并且在引入时,设计人员不想更改控件的公共接口。或许他们认为这是一个高级功能,并希望限制控件新手必须知道的方法的数量,以便能够使它做一些有用的事情。
#1
16
It is protected because DGV inherits the property from Control. And Control.DoubleBuffered is protected. Which makes sense because each derived control should decide for itself to turn that on. And it doesn't make sense for the control user to arbitrarily turn it on or off. The DGV designers decided for off.
它受到保护,因为DGV从Control继承了该属性。并且Control.DoubleBuffered受到保护。这是有道理的,因为每个派生控件都应该决定自己打开它。控制用户随意打开或关闭它是没有意义的。 DGV设计师决定关闭。
One reason they might have decided that is that double buffering actually makes painting slower. The extra step to render the buffer bitmap costs time. It just looks faster to the human eye, you observe the bitmap suddenly appearing. You can't see the time it takes to draw into the bitmap. Unless other controls need to be painted and they get their turn after the DGV, then it is quite visible.
他们可能已经决定的一个原因是双缓冲实际上使绘画变慢。渲染缓冲区位图的额外步骤需要花费时间。只是人眼看起来更快,你会看到突然出现的位图。您无法看到绘制位图所需的时间。除非需要绘制其他控件并且他们在DGV之后轮到他们,否则它是非常明显的。
What you see is the form getting drawn first, with holes where the controls go. Those holes have a white background. Black when you use the TransparencyKey or Opacity property. Each control then gets the Paint event and the holes are filled one-by-one. That effect is perceived as flicker too by the user, although it is a different kind of flicker from the one that DoubleBuffered solves. It is especially noticeable when the background is black.
您看到的是首先绘制的表单,其中包含控件所在的孔。那些洞有白色背景。使用TransparencyKey或Opacity属性时为黑色。然后每个控件获取Paint事件,并逐个填充孔。这种效果被用户感知为闪烁,尽管它与DoubleBuffered解决的闪烁不同。当背景为黑色时尤其明显。
What's needed to solve this problem is that the entire form, with all its controls, is double-buffered. That's not available in Windows Forms. However, Windows XP and later actually support this. Check this thread to see how that's done. Beware that it can have side-effects as documented in that thread.
解决这个问题需要的是整个表单及其所有控件都是双缓冲的。这在Windows窗体中不可用。但是,Windows XP及更高版本实际上支持这一点。检查这个帖子,看看是怎么做的。请注意,它可能具有该线程中记录的副作用。
#2
12
I think its best solution:
我认为它的最佳解决方案:
typeof(DataGridView).InvokeMember(
"DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null,
myDataGridViewObject,
new object[] { true });
found here
#3
4
Inheritance is not needed to turn on doublebuffering on a datagridview. You can do it with reflection on an existing datagridview.
在datagridview上启用doublebuffering不需要继承。您可以使用现有datagridview上的反射来完成此操作。
#4
2
Double buffering by definition uses two buffers and twice the memory for rendering the view of the control into. So, there is some drawback there, however, with the amount of memory you get in a PC now, not many people probably would notice the sacrifice.
根据定义,双缓冲使用两个缓冲区和两倍的内存来渲染控件的视图。因此,有一些缺点,然而,现在你在PC中获得的内存量,并不是很多人可能会注意到牺牲。
No idea why its protected. Maybe the function wasn't available in an early version of the control, and when it was introduced the designers didn't want to change the public interface of the control. Or perhaps they considered it to be an advanced feature and wanted to limit the number of methods someone new to the control would have to grok to be able to make it do something useful.
不知道为什么它受到保护。也许该功能在早期版本的控件中不可用,并且在引入时,设计人员不想更改控件的公共接口。或许他们认为这是一个高级功能,并希望限制控件新手必须知道的方法的数量,以便能够使它做一些有用的事情。