【WinForm.NET开发】在控件上绘图
本文内容
- 控件提供的绘图
- GDI+ 基础知识
- 绘图区域的几何图形
- 释放图形资源
控件的自定义绘制是 Windows 窗体可以轻松完成的众多复杂任务之一。 创作自定义控件时,有许多选项可用于处理控件的图形外观。 如果要创作自定义控件
(即从?Control?继承的控件),则必须提供代码以呈现其图形表示形式。?
如果要创建
复合控件(即从?UserControl?继承的控件或某个
现有的 Windows 窗体控件),则可以替代标准图形表示形式,并提供你自己的图形代码。
如果要在不创建新控件的情况下为现有控件提供自定义呈现,选项会变得更为有限。 但是,对于控件和应用程序,仍有各种各样的图形。
控件呈现涉及以下元素:
- 基类?System.Windows.Forms.Control?提供的绘图功能。
- GDI 图形库的基本元素。
- 绘图区域的几何图形。
- 释放图形资源的过程。
1、控件提供的绘图
基类?Control?通过其?Paint?事件提供绘图功能。 每当控件需要更新其显示时,它都会引发?Paint?事件。
Paint?事件的事件数据类?PaintEventArgs?包含绘制控件所需的数据 - 图形对象的句柄和表示绘制区域的矩形。
public class PaintEventArgs : EventArgs, IDisposable
{
public System.Drawing.Rectangle ClipRectangle {get;}
public System.Drawing.Graphics Graphics {get;}
// Other properties and methods.
}
Graphics?是一个可封装绘图功能的托管类,如本文后面的 GDI 讨论中所述。?ClipRectangle?是?Rectangle?结构的实例,它定义了可在其中绘制控件的可用区域。 控件开发人员可以使用控件的?ClipRectangle?属性来计算?ClipRectangle,如本文后面的几何图形讨论中所述。
OnPaint
控件必须通过重写它从?Control?继承的?OnPaint?方法来提供呈现逻辑。?OnPaint?可访问图形对象和矩形,以通过传递给它的?PaintEventArgs?实例的?Graphics?和?ClipRectangle?属性进行绘制。
下面的代码使用?System.Drawing
?命名空间:
protected override void OnPaint(PaintEventArgs e)
{
// Call the OnPaint method of the base class.
base.OnPaint(e);
// Declare and instantiate a new pen that will be disposed of at the end of the method.
using var myPen = new Pen(Color.Aqua);
// Create a rectangle that represents the size of the control, minus 1 pixel.
var area = new Rectangle(new Point(0, 0), new Size(this.Size.Width - 1, this.Size.Height - 1));
// Draw an aqua rectangle in the rectangle represented by the control.
e.Graphics.DrawRectangle(myPen, area);
}
Control?基类的?OnPaint?方法不实现任何绘图功能,只是调用注册到?Paint?事件的事件委托。 重写?OnPaint?时,应确保调用基类的?OnPaint?方法,以便注册的委托可接收?Paint?事件。 但是,绘制整个表面的控件不应调用基类的?OnPaint,因为这会引起闪烁。
?备注
请勿直接从控件调用?OnPaint;请改为调用?Invalidate?方法(从?Control?继承)或调用?Invalidate?的其他方法。?Invalidate?方法又会调用?OnPaint。 重载?Invalidate?方法,并根据提供给?Invalidatee
?的参数重绘其部分屏幕区域或整个屏幕区域。
控件的?OnPaint?方法中的代码将在第一次绘制控件以及每次刷新该控件时执行。 若要确保在每次调整控件大小时都重新进行绘制,请将下面的行添加到控件的构造函数中:
SetStyle(ControlStyles.ResizeRedraw, true);
OnPaintBackground
Control?基类定义了另一种可用于绘图的方法,即?OnPaintBackground?方法。
protected virtual void OnPaintBackground(PaintEventArgs e);
OnPaintBackground?绘制窗口的背景(并以相同方式绘制形状),并保证速度较快,而?OnPaint?绘制详细信息,速度可能较慢,因为单个绘制请求会合并为一个?Paint?事件,其中涵盖了所有需要重新绘制的区域。 例如,如果想要为控件绘制颜色渐变的背景,则可能需要调用?OnPaintBackground。
虽然?OnPaintBackground?具有类似事件的命名法并采用与?OnPaint
?方法相同的参数,但?OnPaintBackground
?不是真正的事件方法。 不存在?PaintBackground
?事件,并且?OnPaintBackground
?不调用事件委托。 重写?OnPaintBackground
?方法时,无需使用派生类即可调用其基类的?OnPaintBackground
?方法。
2、GDI+ 基础知识
Graphics?类提供用于绘制各种形状(如圆形、三角形、弧形和椭圆形)的方法,以及用于显示文本的方法。?System.Drawing?命名空间包含命名空间和类,它们可用于封装图形元素,如形状(圆形、矩形、弧形等)、颜色、字体、画笔等。
3、绘图区域的几何图形
控件的?ClientRectangle?属性指定可用于用户屏幕上的控件的矩形区域,而?PaintEventArgs?的?ClipRectangle?属性指定所绘制的区域。 当控件的一小部分显示发生变化时,控件可能只需要绘制部分可用区域。 在这些情况下,控件开发人员必须计算要在其中进行绘制的实际矩形,并将其传递到?Invalidate。 采用?Rectangle?或?Region?作为参数的?Invalidate?的重载版本使用该参数生成?PaintEventArgs?的?ClipRectangle?属性。
4、释放图形资源
图形对象成本昂贵,因为它们使用系统资源。 此类对象包括?System.Drawing.Graphics?类的实例以及?System.Drawing.Brush、System.Drawing.Pen?和其他图形类的实例。 请务必仅在需要时才创建图形资源,并在使用完之后立即释放。 如果创建实现?IDisposable?接口的类型的实例,请在使用完该实例之后,调用其?Dispose?方法来释放资源。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!