Window下减少重绘的方法

本文介绍了解决.NET精简框架下控件闪烁问题的三种方法:使用双缓冲显示、仅更新需要刷新的区域及阻止操作系统擦除背景颜色。

这是一个老问题,网上也有很多解决方案。最近自己做的项目又重新折腾了一番,写下来以备遗忘。

1.  使用双缓冲显示的方式

          在.net精简框架下,可以使用Image对象做缓冲。绘图的时候先绘到缓冲中。代码如下:

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        private Image buffImage ;

ExpandedBlockStart.gifContractedBlock.gif        
/**//// <summary>
        
/// 重绘图形,调用此方法以更新图形
        
/// </summary>

        public void Redraw()
ExpandedBlockStart.gifContractedBlock.gif        
{
            
if(buffImage == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                buffImage 
= new Bitmap(Width, Height);
            }

            
using (Graphics g = Graphics.FromImage(buffImage))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//*在这儿绘制图形*/
            }

        }


ExpandedBlockStart.gifContractedBlock.gif        
/**//// <summary>
        
/// 重写OnResize方法
        
/// </summary>
        
/// <param name="e"></param>

        protected override void OnResize(System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
{
            
base.OnResize(e);
            
if(buffImage != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                buffImage.Dispose();
                buffImage 
= null;
            }

            Redraw();
        }


ExpandedBlockStart.gifContractedBlock.gif        
/**//// <summary>
        
/// 重写Dispose方法,释放资源
        
/// </summary>
        
/// <param name="disposing"></param>

        protected override void Dispose(bool disposing)
ExpandedBlockStart.gifContractedBlock.gif        
{
            
if(buffImage!=null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                buffImage.Dispose();
            }

            
base.Dispose(disposing);
        }

 

2.  只更新需要更新的区域,在处理Paint事件时,只画失效的部分。代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
       void Control_Paint(object sender, PaintEventArgs e)
        {
            
if(buffImage != null && !e.ClipRectangle.IsEmpty)
            {
                
//e.Graphics.DrawImage(buffImage,0,0);
                e.Graphics.DrawImage(buffImage,e.ClipRectangle,e.ClipRectangle,GraphicsUnit.Pixel);
            }
        }

3.  告诉操作系统不要擦除背景颜色,这是显示出现闪烁的重要原因,因为每次控件重绘之前,系统默认会使用背景色填充背景,但是背景色通常和真正显示的内容反差比较大,所以出来的效果就会一闪一闪的。要处理这个问题,需要自己处理WM_ERASEBKGND消息,并返回1。这样操作系统将不会自动重绘背景。在.net精简框架中处理windows消息的方法参见另一篇博文".Net精简框加下子类化控件"。

转载于:https://www.cnblogs.com/shangfc/archive/2009/06/05/1497125.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值