导致画面闪烁的关键原因分析:
解决双缓冲的关键技术:
1、设置显示图元控件的几个属性: 必须要设置,否则效果不是很明显!
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
2、窗口刷新一次的过程中,让所有图元同时显示到窗口。
Graphics对象的创建方式:
a、在内存上创建一块和显示控件相同大小的画布,在这块画布上创建Graphics对象。
实现代码(在OnPaint方法中):
Rectangle rect = e.ClipRectangle;
Bitmap bufferimage = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bufferimage);
g.Clear(this.BackColor);
g.SmoothingMode = SmoothingMode.HighQuality; //高质量
g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
foreach (IShape drawobject in doc.drawObjectList)
{
using (Graphics tg = e.Graphics)
{
tg.DrawImage(bufferimage, 0, 0); //把画布贴到画面上
}
b、直接在内存上创建Graphics对象:
Rectangle rect = e.ClipRectangle;
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = myBuffer.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.Clear(this.BackColor);
foreach (IShape drawobject in doc.drawObjectList)
{
if (rect.IntersectsWith(drawobject.Rect))
{
drawobject.Draw(g);
if (drawobject.TrackerState == config.Module.Core.TrackerState.Selected
&& this.CurrentOperator == Enum.Operator.Transfrom)//仅当编辑节点操作时显示图元热点
{
drawobject.DrawTracker(g);
}
}
}
myBuffer.Render(e.Graphics);
g.Dispose();
myBuffer.Dispose();//释放资源
至此,双缓冲问题解决,两种方式的实现效果都一样,但最后一种方式的占有的内存很少,不会出现内存泄露!
或者:
1、在内存中建立一块“虚拟画布”:
Bitmap bmp = new Bitmap(600, 600);
2、获取这块内存画布的Graphics引用:
Graphics g = Graphics.FromImage(bmp);
3、在这块内存画布上绘图:
g.FillEllipse(brush, i * 10, j * 10, 10, 10);
4、将内存画布画到窗口中
this.CreateGraphics().DrawImage(bmp, 0, 0);
还有的方式
在构造函数中加如下代码
代码一:
代码二: