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

Kar*_*arg 15 .net datagridview doublebuffered winforms

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

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

Han*_*ant 19

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

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

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

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

  • 实际上,双缓冲使它明显更快......足够快,肉眼很容易辨别出差异.我很欣赏这个答案,因为它可能是最"正确"的事情,但它不像使用反射设置更改DataGridView上的设置那样实用 (3认同)

daf*_*ftu 16

我认为它的最佳解决方案:

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

这里找到

  • 虽然对于正在搜索如何启用双缓冲区的人有帮助. (4认同)
  • 问题是问为什么它被设置为false,而不是如何覆盖它. (3认同)

Sco*_*ham 5

根据定义,双缓冲使用两个缓冲区和两倍的内存来将控件视图呈现到其中。因此,那里存在一些缺点,但是,由于您现在拥有PC上的内存量,可能没有多少人会注意到这种牺牲。

不知道为什么要保护它。也许该功能在早期版本的控件中不可用,并且在引入该功能时,设计人员不想更改控件的公共接口。或者,也许他们认为它是一项高级功能,并希望限制该控件的新手必须使用的方法数量,以使其能够执行有用的操作。