【WinForm.NET开发】在控件上绘图

本文内容

  1. 控件提供的绘图
  2. GDI+ 基础知识
  3. 绘图区域的几何图形
  4. 释放图形资源

控件的自定义绘制是 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.BrushSystem.Drawing.Pen 和其他图形类的实例。 请务必仅在需要时才创建图形资源,并在使用完之后立即释放。 如果创建实现 IDisposable 接口的类型的实例,请在使用完该实例之后,调用其 Dispose 方法来释放资源。

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉特思米(gitusme)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值