Sviluppo di un controllo Windows Form semplice

In questa sezione vengono illustrati i passaggi chiave necessari per la creazione di un controllo Windows Form personalizzato. Il controllo semplice sviluppato in questa procedura dettagliata consente di modificare l'allineamento della proprietà Text associata al controllo stesso. Non genera né gestisce alcun evento.

Per creare un controllo semplice personalizzato

  1. Definire una classe derivata da System.Windows.Forms.Control.

    Public Class FirstControl
       Inherits Control
       ...
    End Class
    [C#]
    public class FirstControl:Control{...}
    
  2. Definire delle proprietà. La definizione di proprietà non è obbligatoria, in quanto i controlli ereditano numerose proprietà dalla classe Control, ma per la maggior parte dei controlli personalizzati vengono in genere definite proprietà aggiuntive. Nel codice riportato di seguito viene definita una proprietà denominata TextAlignment utilizzata daFirstControlper impostare il formato di visualizzazione per la proprietà Text ereditata da Control. Per ulteriori informazioni sulla definizione di proprietà, vedere Cenni preliminari sulle proprietà.

    ' 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(); 
       }
    }
    

    Quando si imposta una proprietà che modifica la visualizzazione del controllo, è necessario richiamare il metodo Invalidate per ridisegnare il controllo stesso. Invalidate è definito nella classe Control base.

  3. Sottoporre a override il metodo OnPaint protetto ereditato da Control per fornire logica di rendering al controllo. Se non si sottopone a override OnPaint, non sarà possibile disegnare il controllo. Nel codice riportato di seguito il metodo OnPaint visualizza la proprietà Text ereditata da Control con un allineamento predefinito.

    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);
       } 
    }
    

    Nel codice precedente la visualizzazione del testo avviene con l'allineamento predefinito. Nel codice di esempio riportato alla fine di questo argomento viene illustrato come sostituire all'allineamento di Text l'allineamento specificato dalla proprietà TextAlignment, definita al passaggio 2 di questa sezione.

  4. Specificare attributi per il controllo. Gli attributi consentono, in fase di progettazione, la corretta visualizzazione del controllo e delle proprietà e degli eventi a esso associati nelle finestre di progettazione visive. Nel codice riportato di seguito vengono applicati attributi alla proprietà TextAlignment. In una finestra di progettazione, quale Microsoft Visual Studio .NET, con l'attributo Category, illustrato nel codice di esempio, la proprietà viene visualizzata in una categoria logica. Con l'attributo Description viene visualizzata una stringa descrittiva nella parte inferiore della finestra Proprietà quando si seleziona la proprietà TextAlignment. Per ulteriori informazioni sugli attributi, vedere Attributi per componenti in fase di progettazione.

    <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. (facoltativo) Specificare risorse per il controllo. È possibile fornire una risorsa, quale un'immagine bitmap, per il controllo mediante un'opzione di compilazione (/res per C#) che consente di associare risorse al controllo. In fase di esecuzione la risorsa potrà essere recuperata mediante i metodi della classe System.Resources.ResourceManager. Per ulteriori informazioni sulla creazione e sull'utilizzo di risorse, vedere la sezione Esempi di .NET – Procedura: Risorse nelle Guide rapide.

  6. Compilare e distribuire il controllo. Per compilare e distribuire FirstControl, eseguire i seguenti passaggi:

    1. Salvare il codice dell'esempio che segue in un file di origine, quale FirstControl.cs o FirstControl.vb.

    2. Compilare il codice sorgente in un assembly e salvarlo nella directory dell'applicazione. A tal scopo eseguire il seguente comando dalla directory contenente il file di origine.

      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

      L'opzione di compilazione /t:library informa il compilatore che l'assembly creato è una libreria e non un eseguibile. L'opzione /out specifica il percorso e il nome dell'assembly. L'opzione /r fornisce il nome degli assembly ai quali il codice fa riferimento. In questo esempio verrà creato un assembly privato utilizzabile solo dalle proprie applicazioni. Sarà pertanto necessario salvarlo nella directory dell'applicazione. Per ulteriori informazioni sulla creazione del package e sulla distribuzione di un controllo, vedere Distribuzione di applicazioni .NET Framework.

Nell'esempio che segue è riportato il codice di FirstControl. Il controllo è racchiuso nello spazio dei nomi CustomWinControls. Gli spazi dei nomi forniscono un raggruppamento logico di tipi correlati. È possibile creare il controllo in un nuovo spazio dei nomi o in uno spazio dei nomi esistente. In C# la dichiarazione using (Imports in Visual Basic) consente di accedere ai tipi da uno spazio dei nomi senza utilizzare il nome completo dei tipi. Nell'esempio che segue la dichiarazione using consente al codice di accedere alla classe Control da System.Windows.Forms semplicemente come Control anziché dovendo utilizzare il nome completo 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);
      }
   }
}

Utilizzo del controllo personalizzato in un form

Nell'esempio che segue viene illustrato un form semplice che utilizza FirstControl. Tale esempio consentirà di creare tre istanze di FirstControl, ciascuna con un valore differente per la proprietà TextAlignment.

Per compilare ed eseguire l'esempio

  1. Salvare il codice dell'esempio che segue in un file di origine (SimpleForm.cs o SimpleForms.vb).

  2. Compilare il codice sorgente in un assembly eseguibile utilizzando il seguente comando dalla directory contenente il file di origine.

    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 è l'assembly che contiene la classe FirstControl. È necessario che questo assembly si trovi nella stessa directory del file di origine del form che vi accede (SimpleForm.cs o SimpleForms.vb).

  3. Eseguire SimpleForm.exe utilizzando il seguente comando.

    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);
   }
}

Vedere anche

Proprietà dei controlli Windows Form | Eventi nei controlli Windows Form