Condividi tramite


Procedura: Sviluppare un controllo Windows Form semplice

Questa sezione illustra i passaggi principali per la creazione di un controllo Windows Form personalizzato. Il controllo semplice sviluppato in questo tutorial consente di modificare l'allineamento della proprietà Text. Non genera o gestisce eventi.

Per creare un semplice controllo personalizzato

  1. Definire una classe che deriva da System.Windows.Forms.Control.

    Public Class FirstControl
       Inherits Control
    
    End Class
    
    public class FirstControl:Control {}
    
  2. Definire le proprietà. Non è necessario definire le proprietà perché un controllo eredita molte proprietà dalla classe Control, ma la maggior parte dei controlli personalizzati in genere definisce proprietà aggiuntive. Il frammento di codice seguente definisce una proprietà denominata TextAlignment utilizzata da FirstControl per formattare la visualizzazione della proprietà Text ereditata da Control. Per altre informazioni sulla definizione delle proprietà, vedere Panoramica delle proprietà .

    // ContentAlignment is an enumeration defined in the System.Drawing
    // namespace that specifies the alignment of content on a drawing
    // surface.
    private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
    
    ' ContentAlignment is an enumeration defined in the System.Drawing
    ' namespace that specifies the alignment of content on a drawing 
    ' surface.
    Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
    
    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
       
       Get
          Return alignmentValue
       End Get
       Set
          alignmentValue = value
          
          ' The Invalidate method invokes the OnPaint method described 
          ' in step 3.
          Invalidate()
       End Set
    End Property
    

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

  3. Effettua l'override del metodo protetto OnPaint ereditato da Control per fornire la logica di rendering al controllo. Se non si esegue l'override di OnPaint, il controllo non sarà in grado di disegnare se stesso. Nel frammento di codice seguente il metodo OnPaint visualizza la proprietà Text ereditata da Control con l'allineamento specificato dal campo alignmentValue.

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        StringFormat style = new StringFormat();
        style.Alignment = StringAlignment.Near;
        switch (alignmentValue)
        {
            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);
    }
    
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
    
       MyBase.OnPaint(e)
       Dim style As New StringFormat()
       style.Alignment = StringAlignment.Near
       Select Case alignmentValue
          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( _
           me.Text, _
           me.Font, _
           New SolidBrush(ForeColor), _
           RectangleF.op_Implicit(ClientRectangle), _
           style)
    
    End Sub
    
  4. Specificare gli attributi per il controllo. Gli attributi consentono a un progettista visivo di visualizzare il controllo e le relative proprietà ed eventi in modo appropriato a tempo di progettazione. Il frammento di codice seguente applica attributi alla proprietà TextAlignment. In una finestra di progettazione, ad esempio Visual Studio, l'attributo Category (illustrato nel frammento di codice) determina la visualizzazione della proprietà in una categoria logica. L'attributo Description fa sì che venga visualizzata una stringa descrittiva nella parte inferiore della finestra proprietà quando viene selezionata la proprietà TextAlignment. Per altre informazioni sugli attributi, vedere attributi Design-Time per i componenti.

    [
    Category("Alignment"),
    Description("Specifies the alignment of text.")
    ]
    
    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
  5. (facoltativo) Specificare le risorse per il controllo. È possibile fornire una risorsa, ad esempio una bitmap, per il controllo usando un'opzione del compilatore (/res per C#) per creare un pacchetto delle risorse con il controllo. In fase di esecuzione, la risorsa può essere recuperata usando i metodi della classe ResourceManager. Per ulteriori informazioni sulla creazione e sull'uso delle risorse, vedere le risorse nella sezione Applicazioni desktop.

  6. Compilare e distribuire il controllo. Per compilare e distribuire FirstControl, eseguire la procedura seguente:

    1. Salvare il codice nell'esempio seguente in un file di origine, ad esempio FirstControl.cs o FirstControl.vb.

    2. Compilare il codice sorgente in un assembly e salvarlo nella directory dell'applicazione. A tale scopo, eseguire il comando seguente dalla directory che contiene 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 del compilatore /t:library indica al compilatore che l'assembly che si sta creando è 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 a cui fa riferimento il codice. In questo esempio viene creato un assembly privato che solo le applicazioni possono usare. Di conseguenza, è necessario salvarlo nella directory dell'applicazione. Per altre informazioni sulla creazione di pacchetti e sulla distribuzione di un controllo per la distribuzione, vedere Deployment.

L'esempio seguente illustra il codice per FirstControl. Il controllo è racchiuso nello spazio dei nomi CustomWinControls. Uno spazio dei nomi fornisce un raggruppamento logico di tipi correlati. È possibile creare il tuo controllo in uno spazio dei nomi nuovo o esistente. In C#, la dichiarazione di using (in Visual Basic Imports) consente l'accesso ai tipi da uno spazio dei nomi senza usare il nome completo del tipo. Nell'esempio seguente, la dichiarazione using consente al codice di accedere alla classe Control da System.Windows.Forms con il semplice utilizzo di Control, anziché dover usare il nome completo System.Windows.Forms.Control.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{
    public class FirstControl : Control
    {

        public FirstControl()
        {
        }

        // ContentAlignment is an enumeration defined in the System.Drawing
        // namespace that specifies the alignment of content on a drawing
        // surface.
        private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;

        [
        Category("Alignment"),
        Description("Specifies the alignment of text.")
        ]
        public ContentAlignment TextAlignment
        {

            get
            {
                return alignmentValue;
            }
            set
            {
                alignmentValue = value;

                // The Invalidate method invokes the OnPaint method described
                // in step 3.
                Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            StringFormat style = new StringFormat();
            style.Alignment = StringAlignment.Near;
            switch (alignmentValue)
            {
                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);
        }
    }
}
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms


Public Class FirstControl
   Inherits Control

   Public Sub New()
   End Sub 
   
   
   ' ContentAlignment is an enumeration defined in the System.Drawing
   ' namespace that specifies the alignment of content on a drawing 
   ' surface.
   Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
   
   <Category("Alignment"), Description("Specifies the alignment of text.")> _
   Public Property TextAlignment() As ContentAlignment
      
      Get
         Return alignmentValue
      End Get
      Set
         alignmentValue = value
         
         ' The Invalidate method invokes the OnPaint method described 
         ' in step 3.
         Invalidate()
      End Set
   End Property
   
   
   Protected Overrides Sub OnPaint(e As PaintEventArgs)

      MyBase.OnPaint(e)
      Dim style As New StringFormat()
      style.Alignment = StringAlignment.Near
      Select Case alignmentValue
         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( _
          me.Text, _
          me.Font, _
          New SolidBrush(ForeColor), _
          RectangleF.op_Implicit(ClientRectangle), _
          style)

   End Sub

End Class

Utilizzo del controllo personalizzato in un modulo

Nell'esempio seguente viene illustrato un modulo semplice che usa FirstControl. Crea tre istanze di FirstControl, ognuna con un valore diverso per la proprietà TextAlignment.

Per compilare ed eseguire questo esempio

  1. Salvare il codice nell'esempio seguente in un file di origine (SimpleForm.cs o SimpleForms.vb).

  2. Compilare il codice sorgente in un assembly eseguibile eseguendo il comando seguente 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. Questo assembly deve trovarsi nella stessa directory del file di origine per il modulo a cui accede (SimpleForm.cs o SimpleForms.vb).

  3. Eseguire SimpleForm.exe usando il comando seguente.

    SimpleForm
    
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{

    public class SimpleForm : System.Windows.Forms.Form
    {
        private FirstControl firstControl1;

        private System.ComponentModel.Container components = null;

        public SimpleForm()
        {
            InitializeComponent();
        }

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        private void InitializeComponent()
        {
            this.firstControl1 = new FirstControl();
            this.SuspendLayout();

            //
            // firstControl1
            //
            this.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark;
            this.firstControl1.Location = new System.Drawing.Point(96, 104);
            this.firstControl1.Name = "firstControl1";
            this.firstControl1.Size = new System.Drawing.Size(75, 16);
            this.firstControl1.TabIndex = 0;
            this.firstControl1.Text = "Hello World";
            this.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;

            //
            // SimpleForm
            //
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.firstControl1);
            this.Name = "SimpleForm";
            this.Text = "SimpleForm";
            this.ResumeLayout(false);
        }

        [STAThread]
        static void Main()
        {
            Application.Run(new SimpleForm());
        }
    }
}
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms




Public Class SimpleForm
   Inherits System.Windows.Forms.Form

   Private firstControl1 As FirstControl
   
   Private components As System.ComponentModel.Container = Nothing
   
   
   Public Sub New()
      InitializeComponent()
   End Sub 
   
   

   
   
   Private Sub InitializeComponent()
      Me.firstControl1 = New FirstControl()
      Me.SuspendLayout()
      
      ' 
      ' firstControl1
      ' 
      Me.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark
      Me.firstControl1.Location = New System.Drawing.Point(96, 104)
      Me.firstControl1.Name = "firstControl1"
      Me.firstControl1.Size = New System.Drawing.Size(75, 16)
      Me.firstControl1.TabIndex = 0
      Me.firstControl1.Text = "Hello World"
      Me.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter
      
      ' 
      ' SimpleForm
      ' 
      Me.ClientSize = New System.Drawing.Size(292, 266)
      Me.Controls.Add(firstControl1)
      Me.Name = "SimpleForm"
      Me.Text = "SimpleForm"
      Me.ResumeLayout(False)
   End Sub 
    
   
   <STAThread()>  _
   Shared Sub Main()
      Application.Run(New SimpleForm())
   End Sub 
End Class 

Vedere anche