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

发布时间:2024年01月09日

本文内容

  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?方法来释放资源。

文章来源:https://blog.csdn.net/m0_51887793/article/details/135448326
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。