Compartilhar via


O que é um controle personalizado?

Este artigo apresenta controles personalizados e descreve como eles são diferentes dos controles do usuário. Os controles personalizados não fornecem uma superfície de design visual e dependem do código fornecido pelo usuário para se desenharem. Isso é diferente dos controles de usuário que fornecem uma superfície de design visual para agrupar vários controles em uma única unidade reutilizável.

Os controles personalizados são usados quando um controle ou controle de usuário existente não chega perto de fornecer a interface do usuário ou a interatividade necessária. Eles exigem mais esforço de sua parte para implementar totalmente. O tratamento de teclado e mouse ainda é fornecido pelo Windows Forms, mas cabe a você implementar os comportamentos desejados. Não há uma superfície de design fornecida com um controle personalizado, pois todo o desenho é feito por meio do código no OnPaint método. Componentes, como um Timer, ainda podem ser adicionados por meio da superfície de design nãovisual.

Classe base

Há duas classes base para escolher ao criar um controle personalizado:

  • System.Windows.Forms.Control

    Essa é a mesma classe base usada por outros controles do Windows Forms. Você controla diretamente a entrada e a saída do controle.

  • System.Windows.Forms.ScrollableControl

    Alguns controles do Windows Forms usam essa classe base. Esta classe estende Control ao adicionar a capacidade de deslocar o conteúdo.

A menos que você precise rolar o conteúdo do controle personalizado, use Control como sua classe base.

Funcionalidades herdadas

Como a classe base de um controle personalizado é Control, você herda automaticamente a funcionalidade do Windows Forms compartilhada por todos os controles. Aqui estão algumas das funcionalidades que você obtém com um controle personalizado:

  • Entrada de teclado e mouse.
  • Comportamentos de layout, como ancoragem e encaixe.
  • Suporte para uso de teclas de tabulação.
  • Restrições de tamanho mínimo e máximo.

Pintura

A pintura, que significa desenhar o visual do controle, é realizada substituindo o OnPaint método. Para obter mais informações sobre como os controles fazem pintura, consulte Pintura e desenho em controles.

Quando você cria um controle personalizado usando os modelos do Visual Studio, o OnPaint método é substituído automaticamente para você. O modelo faz isso porque você precisa escrever o código para desenhar seu controle. Aqui está um exemplo do que o modelo gera:

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

Um controle personalizado é pintado com o método OnPaint. O único argumento desse método é um PaintEventArgs objeto, que fornece todas as informações e funcionalidades necessárias para renderizar seu controle. PaintEventArgs fornece duas propriedades que são usadas na renderização do controle:

  • PaintEventArgs.ClipRectangle— Representa a parte do controle que precisa ser redesenhada. Isso pode ser todo o controle ou parte do controle.

  • Graphics— Representa a superfície gráfica do controle. Ele fornece vários objetos e métodos orientados a gráficos que fornecem a funcionalidade necessária para desenhar seu controle.

O método OnPaint é chamado sempre que o controle é desenhado ou atualizado na tela, e o objeto PaintEventArgs.ClipRectangle representa o retângulo onde ocorre a pintura. Se todo o controle precisar ser atualizado, PaintEventArgs.ClipRectangle representará o tamanho de todo o controle. Se apenas parte do controle precisar ser atualizada, ela representará apenas a região que precisa ser redesenhada. Um exemplo desse caso seria quando um controle é parcialmente obscurecido por outro controle na interface do usuário e que outro controle é removido, a parte recém-exposta do controle inferior deve ser redesenhada.

O código no método OnPaint de um controle é automaticamente executado quando o controle é desenhado pela primeira vez e sempre que ele é invalidado. Para garantir que o controle seja redesenhado sempre que for redimensionado, adicione a seguinte linha ao construtor do seu controle:

SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)

Exemplo

O snippet de código a seguir é um controle personalizado que renderiza vários retângulos coloridos ao redor da borda do controle.

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

O código anterior cria um controle semelhante à seguinte imagem:

Um controle personalizado, conforme renderizado no Visual Studio. O controle é uma caixa vazia com cores diferentes que a circundam. Cada cor é inserida por um único pixel.

Contexto

Observe que o fundo do controle é pintado na cor SystemColors.Control, mesmo que o código OnPaint não limpe ou preencha o controle com uma cor. O plano de fundo é pintado pelo método OnPaintBackground(PaintEventArgs) antes de OnPaint ser chamado. Substitua OnPaintBackground para manipular o desenho da tela de fundo do controle. A implementação padrão desse método é desenhar a cor e a imagem definidas pelas propriedades BackColor e BackgroundImage, respectivamente.