Compartilhar via


Como desenvolver um controle simples dos Windows Forms

Esta seção explica as etapas principais para a criação de um controle personalizado dos Windows Forms. O controle simples desenvolvido neste passo a passo permite que o alinhamento de sua Text propriedade seja alterado. Ele não gera ou manipula eventos.

Para criar um controle personalizado simples

  1. Defina uma classe derivada de System.Windows.Forms.Control.

    Public Class FirstControl
       Inherits Control
    
    End Class
    
    public class FirstControl:Control {}
    
  2. Defina as propriedades. (Você não é obrigado a definir propriedades, porque um controle herda muitas propriedades da classe, mas a Control maioria dos controles personalizados geralmente define propriedades adicionais.) O fragmento de código a seguir define uma propriedade chamada TextAlignment que FirstControl usa para formatar a Text exibição da propriedade herdada do Control. Para obter mais informações sobre como definir as propriedades, consulte Properties Overview (Visão geral das propriedades).

    // 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 você define uma propriedade que altera a exibição visual do controle, você deve invocar o método para redesenhar o Invalidate controle. Invalidate é definido na classe Controlbase .

  3. Substitua o método protegido OnPaint herdado de para fornecer lógica de Control renderização ao seu controle. Se você não substituir OnPaint, seu controle não será capaz de desenhar a si mesmo. No fragmento de código a seguir, o método exibe a Text propriedade herdada de Control com o OnPaint alinhamento especificado pelo alignmentValue campo.

    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. Forneça atributos para o seu controle. Os atributos permitem que um designer visual exiba adequadamente seu controle, suas propriedades e eventos no tempo de design. O fragmento de código a seguir se aplica aos atributos para a propriedade TextAlignment. Em um designer como o Visual Studio, o Category atributo (mostrado no fragmento de código) faz com que a propriedade seja exibida em uma categoria lógica. O Description atributo faz com que uma cadeia de caracteres descritiva seja exibida na parte inferior da janela Propriedades quando a TextAlignment propriedade é selecionada. Para obter mais informações sobre atributos, consulte Design-Time Attributes for Components (Atributos de tempo de design para componentes).

    [
    Category("Alignment"),
    Description("Specifies the alignment of text.")
    ]
    
    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
  5. (opcional) Forneça recursos para o seu controle. Você pode fornecer um recurso, como um bitmap, para seu controle usando uma opção do compilador (/res para C#) para recursos de pacote com seu controle. Em tempo de execução, o recurso pode ser recuperado usando os ResourceManager métodos da classe. Para obter mais informações sobre a criação e o uso de recursos, consulte Resources in Desktop Apps (Recursos em aplicativos da Área de Trabalho).

  6. Compile e implante seu controle. Para compilar e implantar FirstControl,, execute as seguintes etapas:

    1. Salve o código no exemplo a seguir em um arquivo de origem (como FirstControl.cs ou FirstControl.vb).

    2. Compile o código-fonte em um assembly e salve-o no diretório do aplicativo. Para fazer isso, execute o seguinte comando do diretório que contém o arquivo de origem.

      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
      

      A opção do compilador /t:library informa o compilador que o assembly que você está criando é uma biblioteca (e não um executável). A opção /out especifica o caminho e o nome do assembly. A opção /r fornece o nome dos assemblies referenciados pelo seu código. Neste exemplo, você cria um assembly particular que somente os seus aplicativos podem usar. Portanto, você precisa salvá-lo no diretório do aplicativo. Para obter mais informações sobre o empacotamento e a implantação de um controle para distribuição, consulte Implantação.

O exemplo a seguir mostra o código para FirstControl. O controle é colocado no namespace CustomWinControls. Um namespace fornece um agrupamento lógico de tipos relacionados. Você pode criar seu controle em um namespace novo ou existente. Em C#, a declaração using (no Visual Basic, Imports) permite que os tipos sejam acessados de um namespace sem usar o nome totalmente qualificado do tipo. No exemplo a seguir, a declaração permite que o código acesse a using classe de como simplesmente Control em vez de ter que usar o nome System.Windows.Forms.Controltotalmente qualificado System.Windows.FormsControl .

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

Usando o controle personalizado em um formulário

O exemplo a seguir mostra um formulário simples que usa FirstControl. Ele cria três instâncias de FirstControl, cada uma com um valor diferente para a propriedade TextAlignment.

Para compilar e executar esse exemplo

  1. Salve o código no exemplo a seguir em um arquivo de origem (SimpleForm.cs ou SimpleForms.vb).

  2. Compile o código-fonte em um assembly executável, executando o seguinte comando do diretório que contém o arquivo de origem.

    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 é o assembly que contém a classe FirstControl. Esse assembly deve estar no mesmo diretório que o arquivo de origem para o formulário que o acessa (SimpleForm.cs ou SimpleForms.vb).

  3. Execute SimpleForm.exe usando o seguinte comando.

    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 

Confira também