这是一个老问题,网上也有很多解决方案。最近自己做的项目又重新折腾了一番,写下来以备遗忘。
1. 使用双缓冲显示的方式
在.net精简框架下,可以使用Image对象做缓冲。绘图的时候先绘到缓冲中。代码如下:
Code
private Image buffImage ;
/**//// <summary>
/// 重绘图形,调用此方法以更新图形
/// </summary>
public void Redraw()
{
if(buffImage == null)
{
buffImage = new Bitmap(Width, Height);
}
using (Graphics g = Graphics.FromImage(buffImage))
{
/**//*在这儿绘制图形*/
}
}
/**//// <summary>
/// 重写OnResize方法
/// </summary>
/// <param name="e"></param>
protected override void OnResize(System.EventArgs e)
{
base.OnResize(e);
if(buffImage != null)
{
buffImage.Dispose();
buffImage = null;
}
Redraw();
}
/**//// <summary>
/// 重写Dispose方法,释放资源
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if(buffImage!=null)
{
buffImage.Dispose();
}
base.Dispose(disposing);
}
2. 只更新需要更新的区域,在处理Paint事件时,只画失效的部分。代码如下:
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精简框加下子类化控件"。