Windows 窗体的.Net 框架绘图技术(3)
该示例程序的唯一目的就是演示怎样仅针对部分区域进行图形绘制。
BasicClip示例程序中的彩色矩形区域就是表示窗体的下方和右侧的无效区域。
Regions是一种被用来定义Windows 窗体或者控件区域的对象,调整窗体大小后所获得的Regions就是窗体重绘的最小区域。当程序需要进行绘制的时候仅绘制感兴趣的特殊区域,这样绘制更小的区域就会使程序的运行速度更快。
为了更好的演示Regions的用法,请查看TextCliping示例程序。该程序重载了OnPaintBackground和OnPaint方法,直接重载这些方法比侦听事件更能保证代码在其它的绘制操作之前被调用,而且对于自定义控件的绘制也更加有效。为了清楚起见,示例程序提供了一个Setup方法,该方法定义了全局的Graphics对象。
private void Setup()
{
GraphicsPath textPath = new GraphicsPath();
textPath.AddString(displayString, FontFamily.GenericSerif,
0, 75, new Point(10, 50), new StringFormat());
textRegion = new Region(textPath);
backgroundBrush = new TextureBrush(new Bitmap("CoffeeBeanSmall.jpg"),
WrapMode.Tile);
foregroundBrush = new SolidBrush(Color.Red);
}
上面的Setup方法首先定义一个空的GraphicsPath对象变量textPath,下一步字符串“Windows Forms”的边界被添加到该路径中,围绕这个轮廓创建Region。这样,一个被绘制在窗体表面的以字符串轮廓为区域的Region就被创建了。最后,Setup方法创建以材质刷子为背景和以实色刷子为前景来绘制窗体。
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Graphics bgGraphics = e.Graphics;
bgGraphics.SetClip(textRegion, CombineMode.Exclude);
bgGraphics.FillRectangle(backgroundBrush, e.ClipRectangle);
bgGraphics.Dispose();
}
上面定义的OnPaintBackground方法先立刻调用基类方法,这能够保证所有底层绘制的代码都能够被执行。下一步,从PaintEventArgs中获得Graphics对象,再将Graphics对象的剪切区域定义为textRegion对象。通过指定CombineMode.Exclude参数,明确无论在哪里绘制或怎样绘制Graphics对象都不绘制textRegion区域内部。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics fgGraphics = e.Graphics;
fgGraphics.FillRegion(foregroundBrush, textRegion);
fgGraphics.Dispose();
}
最后,OnPaint事件负责精确的绘制出字符串。可以很容易的通过调用Graphics的FillRegion方法来实现。通过指定的前景刷子foregroundBrush和textRegion且仅是该区域被绘制。结果,Windows 窗体程序在运行之前确实“思考”该怎样进行绘制。
TextClipping示例程序,通过Region定义的Windows Forms字符串。能够使程序在绘制时避开一个区域。
适当的组合使用区域和智能重绘你可以编写出运行速度快且不会引起闪烁的绘制代码,并且比单独使用双重缓冲区绘制还要节省内存的消耗。
结论
如果你的程序确定要进行绘制操作,使用几种技术可以增强绘制性能。确保争取设置控件属性以及适当的Paint事件处理是编写健壮程序的开始。在权衡好利弊后可以使用双重缓冲区技术产生非常“保护视力”的结果。最后,在实际绘制前进行思考到底哪些客户区域或Region需要被绘制将非常有益。
希望通过这篇文章能够使读者更好的理解关于.net框架的绘制技术及其应用。