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. Esse design difere dos controles do usuário, que fornecem uma superfície de design visual para agrupar vários controles em uma única unidade reutilizável.

Use controles personalizados quando um controle existente, seja padrão ou de usuário, não chega perto de oferecer a UI ou a interatividade que você precisa. Eles exigem mais esforço de sua parte para implementar totalmente. O Windows Forms ainda fornece manipulação de teclado e mouse, mas você precisa implementar comportamentos específicos. Um controle personalizado não inclui uma superfície de design porque todo o desenho é feito por meio do código no OnPaint método. Você ainda pode adicionar componentes, como um Timer, por meio da superfície de design nãovisual.

Classe base

Ao criar um controle personalizado, escolha entre duas classes base:

  • System.Windows.Forms.Control

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

  • System.Windows.Forms.ScrollableControl

    Essa classe base é usada por alguns controles do Windows Forms. Estende Control ao adicionar a capacidade de rolar 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

Pintar significa desenhar o visual do controle. Você realiza essa tarefa substituindo o método OnPaint. Para obter mais informações sobre como os controles fazem pintura, consulte Pintura e desenho em controles.

Ao criar um controle personalizado usando os modelos do Visual Studio, você substitui automaticamente o OnPaint método. O template faz isso porque você precisa escrever o código que renderiza o 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

Você pinta um controle personalizado usando o OnPaint método. Esse método usa um único argumento, um PaintEventArgs objeto, que fornece todas as informações e funcionalidades necessárias para renderizar seu controle. PaintEventArgs fornece duas propriedades que você usa na renderização do controle:

  • PaintEventArgs.ClipRectangle— Representa a parte do controle que precisa ser redesenhada. Essa parte pode ser todo o controle ou apenas uma seção dele.

  • 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 à imagem a seguir:

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 OnPaintBackground(PaintEventArgs) método pinta a tela de fundo antes de chamar OnPaint. Substitua OnPaintBackground para manipular o desenho da tela de fundo do controle. A implementação padrão deste método desenha a cor e a imagem definidas, respectivamente, pelas propriedades BackColor e BackgroundImage.