绘制,不再闪烁

                         绘制, 不再闪烁
   
                                        电子科技大学软件学院 03级02班 周银辉

    在绘图或绘制控件过程中最让人郁闷的便是复杂绘制的闪烁问题. 如果您为该问题所困扰,那么您应该注意以下几点:

1, 使用缓冲:
    比如要向Graphics 对象 g 上绘制图形, 你可以在内存中使用一张图片作为缓冲,先将图形绘制到该图片上,绘制完成后再将该图片绘制到g上.
   
None.gif Bitmap buffer  =   new  Bitmap( this .Width,  this .Height);
None.gif
None.gif
using  (Graphics bufferGrfx  =  Graphics.FromImage(buffer))
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//绘制到bufferGrfx上
ExpandedBlockEnd.gif
}

None.gif
None.gif
None.gifRectangle srcRect 
=   this .bounds;
None.gifRectangle destRect 
=  srcRect;
None.gif
None.gifg.DrawImage(buffer, destRect, srcRect, GraphicsUnit.Pixel);


  不用担心两次绘制会带来效率上的损失, 其速度与直接绘制到g上几乎一样快.

2, base.OnPaint(e);
    如果所有的绘制操作都由自己来完成,那么在覆盖OnPaint方法时, 请 不要 使用base.OnPaint(e);

3, e.ClipRectangle
    运用剪辑区域, 这很重要, 很简单地,比如图形区域只有很小一个部分需要更新你就没有必要更新全部图形区域.
    具体说来就是,只有那些和剪辑区域相交(或被剪辑区域包含)的区域才需要绘制.

None.gif
None.gif
// 假设Block对象是程序的最小绘制单元
None.gif
foreach (Block bk  in   this .Blocks)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (e.ClipRectangle.Contains(bk.Bounds) ||
InBlock.gif     e.ClipRectangle.IntersectsWith(bk.Bounds))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//draw bk;
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

4, Refrush(), Invalidate(), Update()
    不要轻易使用Refrush来刷新图形.
    在刷新之前,请先确定要刷新的区域,如果要刷新的区域只是图形区域的一部分,您应该使用Invalidate()来使该区域无效,然后使用Update来更新这个无效区域便可.

5, SetStyle();
    其实在以上几点之前, 应该在控件的构造器(或其他初始化方法)中设置控件样式:
  
None.gif this .SetStyle(ControlStyles.OptimizedDoubleBuffer,  true );
None.gif            
this .SetStyle(ControlStyles.AllPaintingInWmPaint,  true );
None.gif            
这里的ControlStyles有好几个枚举,具体设置那些值,以及它们之间的相互关系,请参考MSDN说明文档.

6, DoubleBuffered
   有好几种标准控件是内置双缓冲的,比如Form,  PictureBox等, 您可以将它们的DoubleBuffered设置为true.来减少闪烁. (当然不要寄希望于仅仅设置该属性便万事大吉了, 不然以上5点不是白说了 : )


-----------------------------------
以上几点仅仅是编程过程中的经验总结,   若还有其他方法请补充  (肯定是有的).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值