使用英语阅读

通过


什么是自定义控件?

本文介绍了自定义控件,并介绍了它们与用户控件的区别。 自定义控件不提供视觉设计界面,依靠用户提供的代码进行绘制。 这不同于提供视觉设计图面的用户控件,用于将多个控件分组到单个可重用单元中。

当现有控件或用户控件不接近提供所需的 UI 或交互性时,将使用自定义控件。 你需要付出更多努力才能完全实现。 键盘和鼠标的处理仍然由 Windows 窗体提供,但任何需要实现的行为均留给你去完成。 自定义控件不提供设计界面,因为所有绘图都通过 OnPaint 方法中的代码完成。 仍可通过非可视化设计界面添加组件(例如 Timer)。

基类

创建自定义控件时,有两个基类可供选择:

除非需要滚动自定义控件的内容,否则请使用 Control 基类。

继承的功能

由于自定义控件的基类是 Control,因此会自动继承由所有控件共享的 Windows 窗体功能。 下面是使用自定义控件获取的一些功能:

  • 键盘和鼠标输入。
  • 布局行为,例如定位和停靠。
  • 支持标签导航。
  • 最小和最大大小限制。

绘制,这意味着绘制控件的视觉对象,是通过重写 OnPaint 方法来实现的。 有关控件如何进行绘制的详细信息,请参阅 控件的绘制和绘图

使用 Visual Studio 模板创建自定义控件时,系统会自动重写此方法。 模板这样做,是因为需要你编写代码来渲染控件。 下面是模板生成的示例:

public partial class CustomControl1 : Control
{
    public CustomControl1()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
}

自定义控件是用OnPaint 方法绘制的。 此方法的单个参数是一个 PaintEventArgs 对象,它提供呈现控件所需的所有信息和功能。 PaintEventArgs 提供用于呈现控件的两个属性:

  • PaintEventArgs.ClipRectangle— 表示需要重新绘制的控件的一部分。 这可以是整个控件或控件的一部分。

  • Graphics— 表示控件的图形图面。 它提供多个面向图形的对象和方法,这些对象提供绘制控件所需的功能。

OnPaint方法会在控件被绘制或刷新到屏幕上时调用,而PaintEventArgs.ClipRectangle对象代表进行绘制的矩形区域。 如果需要刷新整个控件, PaintEventArgs.ClipRectangle 则表示整个控件的大小。 如果只需要刷新控件的一部分,则它仅表示需要重绘的区域。 例如,当控件被用户界面中的另一个控件部分遮盖,并且其他控件被移开时,必须重新绘制控件下方新公开的部分。

控件方法中的 OnPaint 代码在首次绘制控件时以及每当控件失效时运行。 若要确保控件在大小调整时始终重新绘制,请将以下代码行添加到控件的构造函数中:

SetStyle(ControlStyles.ResizeRedraw, true);

示例:

以下代码片段是一个自定义控件,该控件在控件边缘周围呈现多个彩色矩形。

protected override void OnPaint(PaintEventArgs pe)
{
    Rectangle rect = this.ClientRectangle;

    // Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
    // Otherwise, it kind of overlaps the outside edge.
    rect.Width -= 1;
    rect.Height -= 1;

    Pen[] colorPens = new Pen[] { Pens.Blue, Pens.BlueViolet,
                                  Pens.AliceBlue, Pens.CornflowerBlue,
                                  Pens.Cyan, Pens.DarkCyan };

    foreach (Pen pen in colorPens)
    {
        pe.Graphics.DrawRectangle(pen, rect);
        rect.Inflate(-1, -1);
    }

    // Raise the Paint event so users can custom paint if they want.
    base.OnPaint(pe);
}

前面的代码创建如下图所示的控件:

在 Visual Studio 中呈现的自定义控件。控件是一个空框,其边框颜色不同。每个颜色都由单个像素嵌入。

背景

请注意,控件的背景是用 SystemColors.Control 颜色绘制的,即使 OnPaint 代码未清除或用颜色填充控件。 OnPaint 被调用之前,背景实际上是通过 OnPaintBackground(PaintEventArgs) 方法绘制的。 重写 OnPaintBackground 以负责绘制控件的背景区域。 此方法的默认实现是分别绘制由 BackColor 属性设置的颜色和 BackgroundImage 属性设置的图像。