为什么DoubleGffered属性在DataGridView上默认为false,为什么它受到保护?

时间:2008-10-31 05:39:35

标签: .net winforms datagridview doublebuffered

我们遇到DataGridViews的性能问题,其中重绘速度非常慢,并找到解决方案Here来创建派生类型并在控件上启用双缓冲。 (由于DoubleBuffered属性受保护,因此派生类型是必需的)

将DoubleBuffered属性设置为true似乎没有任何缺点。

4 个答案:

答案 0 :(得分:18)

它受到保护,因为DGV从Control继承了该属性。并且Control.DoubleBuffered受到保护。这是有道理的,因为每个派生控件都应该决定自己打开它。对于控制用户来说,任意打开或关闭它是没有意义的。 DGV设计师决定关闭。

他们可能已经决定的一个原因是双缓冲实际上使绘画变慢。渲染缓冲区位图的额外步骤需要花费时间。只是人眼看起来更快,你会发现突然出现的位图。您无法看到绘制位图所需的时间。除非需要对其他控件进行绘制并且在DGV之后轮到他们,所以它非常明显。

您看到的是首先绘制的表单,其中包含控件所在的孔。那些洞有白色背景。使用TransparencyKey或Opacity属性时为黑色。然后每个控件获取Paint事件,并逐个填充孔。这种效果被用户感知为闪烁,尽管它与DoubleBuffered解决的闪烁不同。当背景为黑色时尤其明显。

解决这个问题需要的是整个表单及其所有控件都是双缓冲的。这在Windows窗体中不可用。但是,Windows XP及更高版本实际上支持这一点。检查this thread,看看是如何完成的。请注意,它可能具有该线程中记录的副作用。

答案 1 :(得分:16)

我认为它是最好的解决方案:

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

找到here

答案 2 :(得分:5)

根据定义,双缓冲使用两个缓冲区和两倍的内存来渲染控件的视图。所以,有一些缺点,然而,现在你在PC上获得的内存量,并不是很多人可能会注意到这种牺牲。

不知道为何受到保护。也许该功能在早期版本的控件中不可用,并且在引入时,设计人员不想更改控件的公共接口。或者也许他们认为这是一个高级功能,并希望限制控件新手必须知道的方法的数量,以便能够使它做一些有用的事情。

答案 3 :(得分:4)

turn on doublebuffering on a datagridview不需要继承。您可以使用现有数据网格视图的反射来完成此操作。