Compartilhar via


Criar um controle personalizado simples

Este artigo ensina como criar um controle personalizado do Windows Forms. O controle simples desenvolvido neste artigo imprime os controles Text à esquerda, ao centro ou à direita do controle. O alinhamento do texto pode ser alterado. Esse controle não gera ou manipula eventos.

Neste artigo, você aprenderá a:

  • Adicione uma propriedade e um campo para lidar com a configuração de alinhamento horizontal do texto.
  • Use OnTextChanged para invalidar o controle.
  • Forneça código no OnPaint método para desenhar texto na superfície do controle.

Adicionar um controle personalizado

A primeira etapa é adicionar um controle personalizado ao seu projeto.

  1. No Visual Studio, localize a janela do Gerenciador de Soluções . Clique com o botão direito do mouse no projeto e escolha Adicionar>Novo Item.

    Uma imagem do Visual Studio. Na janela Do Gerenciador de Soluções, o projeto foi clicado com o botão direito do mouse mostrando um menu. Realçado no menu está o item de menu 'Adicionar', que é expandido mostrando um sub menu. No sub menu, o item de menu 'Novo Item' está realçado.

  2. Pesquise o Controle Personalizado e selecione-o.

  3. Defina o nome do arquivo como FirstControl e selecione Adicionar.

  4. Se o modo Design do controle estiver visível, alterne para o modo de exibição de código. Pressione F7 ou selecione o link para alternar para a visualização de código.

    Dica

    Você também pode clicar com o botão direito do mouse no arquivo na janela do Gerenciador de Soluções e selecionar Exibir Código.

Agora você deve examinar o código-fonte do controle personalizado, que é semelhante ao seguinte snippet:

public partial class FirstControl : Control
{
    public FirstControl()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
}
Public Class FirstControl

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
    End Sub

End Class

Adicionar uma propriedade

Crie uma nova propriedade no controle chamado TextAlignment. Essa propriedade ajustará onde o texto é exibido no controle. Com a FirstControl classe, execute as seguintes etapas:

  1. Adicione um campo chamado _textAlignment do tipo HorizontalAlignment.

    private HorizontalAlignment _textAlignment = HorizontalAlignment.Left;
    
    Private _textAlignment As HorizontalAlignment = HorizontalAlignment.Left
    
  2. Encapsular o campo em uma propriedade chamada TextAlignment. Ao definir a propriedade, chame o método Invalidate para forçar o controle a se redesenhar.

    public HorizontalAlignment TextAlignment
    {
        get => _textAlignment;
        set
        {
            _textAlignment = value;
            Invalidate();
        }
    }
    
    Public Property TextAlignment As HorizontalAlignment
        Get
            Return _textAlignment
        End Get
    
        Set(value As HorizontalAlignment)
            _textAlignment = value
            Invalidate()
        End Set
    End Property
    
  3. Adicione os atributos a seguir à propriedade para integrá-la à janela Propriedades no Visual Studio.

    • Category— A categoria aplicada à propriedade.

    • Description— A descrição da propriedade.

    • DefaultValue— Um valor padrão para a propriedade.

      O valor padrão permite que a propriedade seja redefinida pelo designer. Ele também ajuda a determinar quando a propriedade deve ser serializada para o code-behind, pois os valores padrão não são serializados.

    [System.ComponentModel.Category("Alignment"),
    System.ComponentModel.Description("Specifies the alignment of text."),
    System.ComponentModel.DefaultValue(HorizontalAlignment.Left)]
    public HorizontalAlignment TextAlignment
    
    <System.ComponentModel.Category("Alignment"),
    System.ComponentModel.Description("Specifies the alignment of text."),
    System.ComponentModel.DefaultValue(HorizontalAlignment.Left)>
    Public Property TextAlignment As HorizontalAlignment
    

Manipular texto alterado

A TextAlignment propriedade chama Invalidate para que o controle se redesenhe. Isso garante que o alinhamento correto seja usado instantaneamente quando a renderização do Text controle ocorre. No entanto, se a Text propriedade for alterada, nada será atualizado porque Text não chamará Invalidate. No entanto, a propriedade chama o método OnTextChanged, que você pode substituir para chamar Invalidate e forçar o controle a se repintar.

Com a FirstControl classe, execute as seguintes etapas:

  1. Substituir o método OnTextChanged.
  2. Chame base.OnTextChanged para que o evento TextChanged seja acionado, conforme esperado pelos consumidores do componente.
  3. Chame o método Invalidate para forçar a renderização.

Seu código deve ser semelhante ao seguinte trecho:

protected override void OnTextChanged(EventArgs e)
{
    base.OnTextChanged(e);
    Invalidate();
}
Protected Overrides Sub OnTextChanged(e As EventArgs)
    MyBase.OnTextChanged(e)
    Invalidate()
End Sub

Pintar o controle

A última parte do controle personalizado é a pintura. Com a FirstControl classe, execute as seguintes etapas:

  1. Localize o OnPaint método gerado pelo modelo. Se ele estiver ausente, substitua-o da classe base.

  2. Crie uma nova variável StringFormat chamada style.

    StringFormat style = new();
    
    Dim style As New StringFormat
    

    O System.Drawing.StringFormat tipo encapsula informações de layout de texto e fornece acesso ao alinhamento.

  3. Com base em TextAlignment, defina a propriedade style.Alignment para o valor apropriado.

    style.Alignment = TextAlignment switch
    {
        // Map the HorizontalAlignment enum to the StringAlignment enum
        HorizontalAlignment.Left => StringAlignment.Near,
        HorizontalAlignment.Right => StringAlignment.Far,
        HorizontalAlignment.Center => StringAlignment.Center,
        
        // Default to Near alignment
        _ => StringAlignment.Near
    };
    
    'Map the HorizontalAlignment enum to the StringAlignment enum
    Select Case TextAlignment
        Case HorizontalAlignment.Left
            style.Alignment = StringAlignment.Near
        Case HorizontalAlignment.Right
            style.Alignment = StringAlignment.Far
        Case HorizontalAlignment.Center
            style.Alignment = StringAlignment.Center
    End Select
    
  4. Desenhe a propriedade Text com Graphics.DrawString.

    // Create the brush and automatically dispose it.
    using SolidBrush foreBrush = new(ForeColor);
    
    // Call the DrawString method to write text.
    // Text, Font, and ClientRectangle are inherited properties.
    pe.Graphics.DrawString(Text, Font, foreBrush, ClientRectangle, style);
    
    'Create the brush and automatically dispose it.
    Using foreBrush As New SolidBrush(ForeColor)
        'Call the DrawString method to write text.
        'Text, Font, and ClientRectangle are inherited properties.
        e.Graphics.DrawString(Text, Font, foreBrush, ClientRectangle, style)
    End Using
    

    Importante

    O Graphics.DrawString método usa um Brush para a cor do texto. Brushes deve ser descartado após o uso.

    O Graphics.DrawString método usa opções de texto, fonte, cor e formatação para desenhar uma cadeia de caracteres.

  5. Chame base.OnPaint para garantir que o Paint evento seja acionado.

    base.OnPaint(pe);
    
    MyBase.OnPaint(e)
    
  6. Salve o arquivo de código e compile o projeto. Depois que o projeto for compilado, o Visual Studio adicionará o controle personalizado à janela caixa de ferramentas quando você abrir o Designer Visual.

Seu código deve ser semelhante ao seguinte trecho:

public partial class FirstControl : Control
{
    private HorizontalAlignment _textAlignment = HorizontalAlignment.Left;

    [System.ComponentModel.Category("Alignment"),
    System.ComponentModel.Description("Specifies the alignment of text."),
    System.ComponentModel.DefaultValue(HorizontalAlignment.Left)]
    public HorizontalAlignment TextAlignment
    {
        get => _textAlignment;
        set
        {
            _textAlignment = value;
            Invalidate();
        }
    }

    public FirstControl()
    {
        InitializeComponent();
    }

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        StringFormat style = new();

        style.Alignment = TextAlignment switch
        {
            // Map the HorizontalAlignment enum to the StringAlignment enum
            HorizontalAlignment.Left => StringAlignment.Near,
            HorizontalAlignment.Right => StringAlignment.Far,
            HorizontalAlignment.Center => StringAlignment.Center,
            
            // Default to Near alignment
            _ => StringAlignment.Near
        };

        // Create the brush and automatically dispose it.
        using SolidBrush foreBrush = new(ForeColor);

        // Call the DrawString method to write text.
        // Text, Font, and ClientRectangle are inherited properties.
        pe.Graphics.DrawString(Text, Font, foreBrush, ClientRectangle, style);

        base.OnPaint(pe);
    }
}
Public Class FirstControl

    Private _textAlignment As HorizontalAlignment = HorizontalAlignment.Left

    <System.ComponentModel.Category("Alignment"),
    System.ComponentModel.Description("Specifies the alignment of text."),
    System.ComponentModel.DefaultValue(HorizontalAlignment.Left)>
    Public Property TextAlignment As HorizontalAlignment
        Get
            Return _textAlignment
        End Get

        Set(value As HorizontalAlignment)
            _textAlignment = value
            Invalidate()
        End Set
    End Property

    Protected Overrides Sub OnTextChanged(e As EventArgs)
        MyBase.OnTextChanged(e)
        Invalidate()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim style As New StringFormat

        'Map the HorizontalAlignment enum to the StringAlignment enum
        Select Case TextAlignment
            Case HorizontalAlignment.Left
                style.Alignment = StringAlignment.Near
            Case HorizontalAlignment.Right
                style.Alignment = StringAlignment.Far
            Case HorizontalAlignment.Center
                style.Alignment = StringAlignment.Center
        End Select

        'Create the brush and automatically dispose it.
        Using foreBrush As New SolidBrush(ForeColor)
            'Call the DrawString method to write text.
            'Text, Font, and ClientRectangle are inherited properties.
            e.Graphics.DrawString(Text, Font, foreBrush, ClientRectangle, style)
        End Using
        MyBase.OnPaint(e)
    End Sub

End Class