共用方式為


什麼是自定義控件?

本文介紹自定義控件,並說明它們與使用者控件的不同。 自定義控制項不提供可視化設計介面,並依賴使用者提供的程式代碼來繪製自己。 這與使用者控件不同,這些控件提供可視化設計介面,將多個控件分組成單一可重複使用的單位。

當現有的控件或使用者控件未接近提供您需要的UI或互動性時,會使用自定義控件。 它們需要您更努力才能完全實作。 Windows Forms 仍然提供鍵盤和滑鼠處理,但任何功能或動作都需要您自行實作。 自定義控制項沒有提供設計介面,因為所有繪圖都是透過 OnPaint 方法中的程式碼完成。 元件,例如 Timer,仍然可以透過非視覺設計介面來新增。

基類

建立自定義控件時,有兩個基類可供選擇:

除非您需要卷動自定義控件的內容,否則請使用 Control 作為基類。

繼承的功能

由於自定義控件的基類是 Control,因此您會自動繼承所有控件共用的 Windows Forms 功能。 以下是您使用自訂控制項取得的一些功能:

  • 鍵盤和滑鼠輸入。
  • 配置行為,例如錨定和停駐。
  • 支援索引標籤。
  • 最小和最大大小限制。

繪圖

繪圖,即繪製控制項的畫面,是透過覆寫OnPaint方法來實現的。 如需了解有關控件的繪製方式的詳細資訊,請參閱 在控件上繪畫和繪圖

當您使用 Visual Studio 範本建立自訂控制項時,OnPaint 方法會自動為您覆蓋。 範本會執行此動作,因為您必須撰寫程式代碼來繪製控件。 以下是範本產生的範例:

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

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

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
    End Sub

End Class

自定義控件會使用 OnPaint 方法繪製。 此方法的單一 PaintEventArgs 自變數是 物件,可提供轉譯控件所需的所有資訊和功能。 PaintEventArgs 提供用於轉譯控件的兩個屬性:

  • PaintEventArgs.ClipRectangle—表示需要重新繪製之控件的一部分。 這可以是整個控件或控件的一部分。

  • Graphics—代表控件的圖形介面。 它提供數個圖形導向的物件和方法,提供繪製控件所需的功能。

每當在畫面上繪製或刷新控制項時,會呼叫OnPaint方法,而PaintEventArgs.ClipRectangle物件代表進行繪製的矩形區域。 如果需要重新整理整個控件, PaintEventArgs.ClipRectangle 則表示整個控件的大小。 如果只需要重新整理控件的一部分,它就只代表需要重新繪製的區域。 例如,當使用者介面中的一個控件部分被另一個控件遮住,並且該遮蔽的控件被移走後,必須重新繪製露出的下方控件部分。

當控制項首次被繪製或每當它被標記為無效時,控制項方法中的 OnPaint 程式碼將會執行。 若要確保您的控件每次重設大小都會重新繪製,請將下列這一行新增至控件的建構函式:

SetStyle(ControlStyles.ResizeRedraw, true);
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);
}
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

    Dim rect As Rectangle = Me.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

    Dim colorPens As Pen() = {Pens.Blue, Pens.BlueViolet,
                                Pens.AliceBlue, Pens.CornflowerBlue,
                                Pens.Cyan, Pens.DarkCyan}

    For Each curPen As Pen In colorPens

        e.Graphics.DrawRectangle(curPen, rect)
        rect.Inflate(-1, -1)

    Next

    'Raise the Paint event so users can custom paint if they want.
    MyBase.OnPaint(e)

End Sub

先前的程式代碼會建立看起來像下圖的控制項:

Visual Studio 中渲染的自定義控件。控件是一個空白方塊,其邊框由不同色彩組成。每個色彩均內縮一個像素。

背景

請注意,控件的背景會以 SystemColors.Control 色彩繪製,即使程式 OnPaint 代碼未清除或以色彩填滿控件。 在OnPaintBackground(PaintEventArgs)被呼叫之前,背景其實是由OnPaint方法繪製的。 重寫 OnPaintBackground 以處理控制項的背景繪製。 此方法的預設實作是分別繪製由BackColor屬性設定的色彩和由BackgroundImage屬性設定的影像。