共用方式為


開發簡單 Windows Form 控制項

本章節逐步為您解說撰寫自訂 Windows Form 控制項的重要步驟。依照這個逐步解說開發的簡單控制項允許變更其 Text 屬性的對齊。它不會引發或處理事件。

若要建立簡單自訂控制項

  1. 定義衍生自 System.Windows.Forms.Control 的類別。

    Public Class FirstControl
       Inherits Control
       ...
    End Class
    [C#]
    public class FirstControl:Control{...}
    
  2. 定義屬性。(您不需要定義屬性,因為控制項將從 Control 類別繼承許多屬性,但大部分自訂控制項通常確實會定義額外屬性)。下列程式碼片段定義名為 TextAlignment 的屬性,是 FirstControl 用來格式化繼承自 Control Text 屬性的顯示。如需定義屬性的詳細資訊,請參閱屬性概觀

    ' ContentAlignment is an enumeration defined in the System.Drawing
    ' namespace that specifies the alignment of content on a drawing 
    ' surface.
    Private alignment As ContentAlignment = ContentAlignment.MiddleLeft
    
    Public Property TextAlignment() As ContentAlignment
      Get
         Return alignment
      End Get
      Set
         alignment = value
         ' The Invalidate method invokes the OnPaint method described 
         ' in step 3.
         Invalidate()
      End Set
    End Property
    [C#]
    // ContentAlignment is an enumeration defined in the System.Drawing
    // namespace that specifies the alignment of content on a drawing 
    // surface.
    private ContentAlignment alignment = ContentAlignment.MiddleLeft;
    
    public ContentAlignment TextAlignment {
       get {
          return alignment;
       }
       set {
          alignment = value;
          // The Invalidate method invokes the OnPaint method described 
          // in step 3.
          Invalidate(); 
       }
    }
    

    當您設定會變更控制項視覺顯示的屬性時,您必須叫用 Invalidate 方法來重繪控制項。Invalidate 定義於基底類別 Control 中。

  3. 覆寫保護的 (Protected) OnPaint 方法 (繼承自 Control) 來提供您控制項的呈現邏輯。如果您不覆寫 OnPaint,您的控制項將無法自行繪圖。在下列程式碼片段中,OnPaint 方法以預設的對齊來顯示繼承自 ControlText 屬性。

    Public Class FirstControl
       Inherits Control
    
       Public Sub New()
          ...
       End Sub
    
       Protected Overrides Sub OnPaint(e As PaintEventArgs)
          MyBase.OnPaint(e)
          e.Graphics.DrawString(Text, Font, New SolidBrush(ForeColor), RectangleF.op_Implicit(ClientRectangle), style)
       End Sub
    End Class
    [C#]
    public class FirstControl : Control{
       public FirstControl() {...}
       protected override void OnPaint(PaintEventArgs e) {
          base.OnPaint(e);
          e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle, style);
       } 
    }
    

    前面程式碼以預設對齊顯示文字。這個主題結尾的程式碼範例示範如何變更 Text 的對齊為 TextAlignment 屬性 (稍早在本章節中於步驟 2 定義) 所指定的對齊。

  4. 提供屬性給您的控制項。屬性讓視覺設計工具能夠在設計階段適當顯示您的控制項和它的屬性和事件。下列程式碼片段套用屬性於 TextAlignment 屬性。在設計工具 (例如 Microsoft Visual Studio .NET) 中,Category 屬性 (顯示在程式碼片段中) 會使屬性顯示在邏輯分類之下。Description 屬性在選取 TextAlignment 屬性時會致使說明字串顯示於屬性視窗底部。如需詳細資訊,請參閱元件的設計階段屬性

    <Category("Alignment"), _
    Description("Specifies the alignment of text.")> _  
    Public Property TextAlignment() As ContentAlignment
       ...
    End Class
    [C#]
    [
    Category("Alignment"),
    Description("Specifies the alignment of text.")
    ]
    public ContentAlignment TextAlignment {...}
    
  5. (選擇性) 提供資源給您的控制項。您可以使用編譯器 (Compiler) 選項 (在 C# 為 /res),將資源與您的控制項一起封裝 (Package),以提供資源 (例如點陣圖) 給您的控制項。在 Run Time,資源可以使用 System.Resources.ResourceManager 類別的方法來擷取。如需建立和使用資源的詳細資訊,請參閱 .NET 範例 - 處理方法:資源快速入門。

  6. 編譯和部署您的控制項。若要編譯和部署 FirstControl,請執行下列步驟。

    1. 儲存下列範例中的程式碼至原始程式檔 (例如 FirstControl.cs 或 FirstControl.vb)。

    2. 將原始程式碼編譯成組件 (Assembly),並將它儲存在您應用程式的目錄。若要達成這點,請從含有原始程式檔的目錄中執行下列命令。

      vbc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.vb

      csc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.cs

      編譯器選項告訴編譯器,您正在建立的組件是程式庫 (而不是可執行檔)。/out 選項指定組件的路徑和名稱。/r 選項提供您程式碼所參考組件的名稱。在這個範例中,您建立只有您的應用程式可以使用的私用 (Private) 組件。因此您必須將它儲存於您應用程式的目錄。如需封裝和部署散發的控制項的詳細資訊,請參閱部署 .NET Framework 應用程式

下列範例示範 FirstControl 的程式碼。控制項被封入在命名空間 CustomWinControls 中。命名空間提供相關型別的邏輯群組。您可以在新的或現有命名空間中建立您的控制項。在 C# 中,using 宣告 (在 Visual Basic 中為 Imports) 允許型別從命名空間來存取,而不需使用型別的完整名稱。在下列範例中,using 宣告允許程式碼只是用簡單如 Control 的方式從 System.Windows.Forms 存取類別 Control,取代必須使用完整名稱 System.Windows.Forms.Control

Option Explicit
Option Strict

Imports System
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Drawing

Namespace CustomWinControls
   Public Class FirstControl
      Inherits Control
      Private alignment As ContentAlignment = ContentAlignment.MiddleLeft

      <Category("Alignment"), _
      Description("Specifies the alignment of text.")> _
      Public Property TextAlignment() As ContentAlignment
         Get
            Return alignment
         End Get
         Set
            alignment = value
            ' The Invalidate method invokes the OnPaint method.
            Invalidate()
         End Set
      End Property
      
      ' OnPaint aligns text, as specified by the 
      ' TextAlignment property, by passing a parameter
      ' to the DrawString method of the System.Drawing.Graphics object.
      Protected Overrides Sub OnPaint(e As PaintEventArgs)
         MyBase.OnPaint(e)
         Dim style As New StringFormat()
         style.Alignment = StringAlignment.Near
         Select Case alignment
            Case ContentAlignment.MiddleLeft
               style.Alignment = StringAlignment.Near
            Case ContentAlignment.MiddleRight
               style.Alignment = StringAlignment.Far
            Case ContentAlignment.MiddleCenter
               style.Alignment = StringAlignment.Center
         End Select
         ' Call the DrawString method of the System.Drawing class to write   
         ' text. Text and ClientRectangle are properties inherited from
         ' Control.
         e.Graphics.DrawString(Text, Font, New SolidBrush(ForeColor), RectangleF.op_Implicit(ClientRectangle), style)
      End Sub
   End Class
End Namespace
[C#]
namespace CustomWinControls {
   using System;
   using System.ComponentModel;
   using System.Windows.Forms;
   using System.Drawing;
   public class FirstControl : Control {
      private ContentAlignment alignment = ContentAlignment.MiddleLeft;
      
      [
       Category("Alignment"),
       Description("Specifies the alignment of text.")
      ]
      public ContentAlignment TextAlignment {
         get {
            return alignment;
         }
         set {
            alignment = value;
            // The Invalidate method invokes the OnPaint method.
            Invalidate();
         }
      }

      // OnPaint aligns text, as specified by the 
      // TextAlignment property, by passing a parameter
      // to the DrawString method of the System.Drawing.Graphics object.
      protected override void OnPaint(PaintEventArgs e) {
         base.OnPaint(e);
         StringFormat style = new StringFormat();
         style.Alignment = StringAlignment.Near;
         switch (alignment) {
            case ContentAlignment.MiddleLeft:
               style.Alignment = StringAlignment.Near;
               break;
            case ContentAlignment.MiddleRight:
               style.Alignment = StringAlignment.Far;
               break;
            case ContentAlignment.MiddleCenter:
               style.Alignment = StringAlignment.Center;
               break;
         }
         // Call the DrawString method of the System.Drawing class to write   
         // text. Text and ClientRectangle are properties inherited from
         // Control.
         e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle, style);
      }
   }
}

在網頁上使用自訂控制項

下列範例示範使用 FirstControl 的簡單表單。它建立三個 FirstControl 的執行個體,各個都有不同的 TextAlignment 屬性值。

編譯和執行這個範例

  1. 儲存下列範例中的程式碼至原始程式檔 (簡單 Form.cs 或 簡單 Forms.vb)。

  2. 從含有原始程式檔的目錄執行下列命令,將原始程式碼編譯成可執行組件。

    vbc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.vb

    csc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.cs

    CustomWinControls.dll 為含有類別 FirstControl 的組件。這個組件必須位於存取它的表單 (簡單 Form.cs 或 簡單 Forms.vb) 的原始程式檔的相同目錄。

  3. 使用下列命令執行簡單的 Form.exe。

    SimpleForm

Option Explicit
Option Strict

Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports CustomWinControls

Class SimpleForm
   Inherits Form
   Private leftControl As FirstControl
   Private centerControl As FirstControl
   Private rightControl As FirstControl
   
   Protected Overloads Overrides Sub Dispose(disposing as Boolean)
      MyBase.Dispose(disposing)
   End Sub
   
   
   Public Sub New()
      leftControl = New FirstControl()
      With leftControl
         .Text = "Left"
         .Location = New Point(50, 50)
         .Size = New Size(50, 50)
      End With
      Controls.Add(leftControl)
      
      centerControl = New FirstControl()
      With centerControl
         .TextAlignment = ContentAlignment.MiddleCenter
         .Text = "Center"
         .Location = New Point(125, 50)
         .Size = New Size(50, 50)
      End With
      Controls.Add(centerControl)
      
      rightControl = New FirstControl()
      With rightControl
         .TextAlignment = ContentAlignment.MiddleRight
         .Text = "Right"
         .Location = New Point(200, 50)
         .Size = New Size(50, 50)
      End With
      Controls.Add(rightControl)
   End Sub

   <STAThread()> _
   Public Shared Sub Main()
      Dim myForm As New SimpleForm()
      myForm.Text = "Uses FirstControl"
      myForm.Size = New Size(400, 150)
      Application.Run(myForm)
   End Sub
End Class
[C#]
using System;
using System.Windows.Forms;
using System.Drawing;
using CustomWinControls;

class SimpleForm : Form {
   private FirstControl left;
   private FirstControl center;
   private FirstControl right;
   
   protected override void Dispose(bool disposing) {
      base.Dispose(disposing);
   }

   public SimpleForm() : base() {
      left = new FirstControl();
      left.Text = "Left";
      left.Location = new Point(50, 50);
      left.Size = new Size(50, 50);
      Controls.Add(left);
      
      center = new FirstControl();
      center.TextAlignment = ContentAlignment.MiddleCenter;
      center.Text = "Center";
      center.Location = new Point(125, 50);
      center.Size = new Size(50, 50);
      Controls.Add(center);
      
      right = new FirstControl();
      right.TextAlignment = ContentAlignment.MiddleRight;
      right.Text = "Right";
      right.Location = new Point(200, 50);
      right.Size = new Size(50, 50);
      Controls.Add(right);
   }
   
   [STAThread]
   public static void Main(string[] args) {
      Form form = new SimpleForm();
      form.Text = "Uses FirstControl";
      form.Size = new Size(400, 150);
      Application.Run(form);
   }
}

請參閱

Windows Form 控制項中的屬性 | Windows Form 控制項中的事件