Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A pintura personalizada de controles é uma das muitas tarefas complicadas facilitadas pelo Windows Forms. Ao criar um controle personalizado, você tem muitas opções disponíveis para lidar com a aparência gráfica do controle. Se você estiver criando um controle personalizado, ou seja, um controle do qual herda Control, use o código para renderizar sua representação gráfica.
Se você estiver criando um controle composto—ou seja, um controle que herda de UserControl ou de um dos controles existentes do Windows Forms—você pode substituir a representação gráfica padrão e fornecer seu próprio código gráfico.
Se você quiser fornecer renderização personalizada para um controle existente sem criar um novo controle, manipule o Paint evento que permite desenhar sobre um controle.
Os elementos a seguir estão envolvidos na renderização de controles:
- A funcionalidade de desenho fornecida pela classe base System.Windows.Forms.Control.
- Os elementos essenciais da biblioteca gráfica GDI.
- A geometria da região de desenho.
- O procedimento para liberar recursos gráficos.
Desenho fornecido pelo controle
A classe Control base fornece funcionalidade de desenho por meio de seu Paint evento. Um controle gera o evento Paint sempre que precisa atualizar sua exibição e concluir sua renderização. Para obter mais informações sobre eventos no .NET, consulte Manipulação e geração de eventos.
A classe de dados de evento para o Paint, PaintEventArgs, contém os dados necessários para desenhar um controle - uma referência a um objeto gráfico e um retângulo que define a região a ser desenhada.
public class PaintEventArgs : EventArgs, IDisposable
{
public System.Drawing.Rectangle ClipRectangle {get;}
public System.Drawing.Graphics Graphics {get;}
// Other properties and methods.
}
Public Class PaintEventArgs
Inherits EventArgs
Implements IDisposable
Public ReadOnly Property ClipRectangle As System.Drawing.Rectangle
Public ReadOnly Property Graphics As System.Drawing.Graphics
' Other properties and methods.
End Class
Graphics é uma classe gerenciada que encapsula a funcionalidade de desenho, conforme descrito na discussão sobre GDI mais adiante neste artigo. O ClipRectangle é uma instância da Rectangle estrutura e define a área disponível na qual um controle pode desenhar. Um desenvolvedor de controle pode calcular o ClipRectangle usando a ClipRectangle propriedade de um controle, conforme descrito na discussão sobre geometria mais adiante neste artigo.
OnPaint
Um controle deve fornecer lógica de renderização sobrescrevendo o método OnPaint, que herda de Control. OnPaint obtém acesso a um objeto gráfico e a um retângulo para desenhar por meio das propriedades Graphics e ClipRectangle da instância PaintEventArgs passada para ele.
O código a seguir usa o System.Drawing
namespace:
protected override void OnPaint(PaintEventArgs e)
{
// Call the OnPaint method of the base class.
base.OnPaint(e);
// Declare and instantiate a new pen that will be disposed of at the end of the method.
using var myPen = new Pen(Color.Aqua);
// Create a rectangle that represents the size of the control, minus 1 pixel.
var area = new Rectangle(new Point(0, 0), new Size(this.Size.Width - 1, this.Size.Height - 1));
// Draw an aqua rectangle in the rectangle represented by the control.
e.Graphics.DrawRectangle(myPen, area);
}
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
' Declare and instantiate a drawing pen.
Using myPen = New System.Drawing.Pen(Color.Aqua)
' Create a rectangle that represents the size of the control, minus 1 pixel.
Dim area = New Rectangle(New Point(0, 0), New Size(Me.Size.Width - 1, Me.Size.Height - 1))
' Draw an aqua rectangle in the rectangle represented by the control.
e.Graphics.DrawRectangle(myPen, area)
End Using
End Sub
O OnPaint método da classe base Control não implementa nenhuma funcionalidade de desenho, mas apenas invoca os delegados de evento registrados com o Paint evento. Ao substituir OnPaint, você normalmente deve invocar o método OnPaint da classe base para que os delegados registrados recebam o evento Paint. No entanto, os controles que pintam toda a sua superfície não devem invocar o OnPaint da classe base, pois isso introduz tremulação.
Observação
Não invoque OnPaint diretamente do seu controle; em vez disso, invoque o Invalidate método (herdado de Control) ou algum outro método que chame Invalidate. O método Invalidate, por sua vez, invoca OnPaint. O Invalidate método está sobrecarregado e, dependendo dos argumentos fornecidos ao Invalidatee
, redesenha parte ou toda a área da tela.
O código no método OnPaint do controle será executado quando o controle for desenhado pela primeira vez e sempre que for atualizado. Para garantir que o controle seja redesenhado sempre que ele for redimensionado, adicione a seguinte linha ao construtor do seu controle:
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)
OnPaintBackground
A classe base Control define outro método que é útil para desenhar, o OnPaintBackground método.
protected virtual void OnPaintBackground(PaintEventArgs e);
Protected Overridable Sub OnPaintBackground(e As PaintEventArgs)
OnPaintBackground pinta o fundo (e, dessa forma, a forma) da janela e é garantido que será rápido, enquanto OnPaint pinta os detalhes e pode ser mais lento porque as solicitações de pintura individuais são combinadas em um Paint evento que cobre todas as áreas que precisam ser redesenhadas. Talvez você queira invocar o OnPaintBackground se, por exemplo, quiser desenhar um plano de fundo colorido de gradiente para seu controle.
Embora OnPaintBackground tenha uma nomenclatura semelhante a um evento e use o mesmo argumento que o OnPaint
método, OnPaintBackground
não é um método de evento verdadeiro. Não há nenhum PaintBackground
evento e OnPaintBackground
não invoca delegados de evento. Ao substituir o OnPaintBackground
método, uma classe derivada não é necessária para invocar o OnPaintBackground
método de sua classe base.
Noções básicas sobre a GDI+
A Graphics classe fornece métodos para desenhar várias formas, como círculos, triângulos, arcos e elipses, e métodos para exibir texto. O System.Drawing namespace contém namespaces e classes que encapsulam elementos gráficos, como formas (círculos, retângulos, arcos e outros), cores, fontes, pincéis e assim por diante.
Geometria da região de desenho
A ClientRectangle propriedade de um controle especifica a região retangular disponível para o controle na tela do usuário, enquanto a ClipRectangle propriedade de PaintEventArgs especifica a área que é pintada. Um controle pode precisar pintar apenas uma parte da sua área disponível, como é o caso quando uma pequena seção da exibição do controle é alterada. Nessas situações, um desenvolvedor de controles deve calcular o retângulo real para desenhar e passá-lo para Invalidate. As versões sobrecarregadas de Invalidate que usam um Rectangle ou Region como um argumento usam esse argumento para gerar a ClipRectangle propriedade de PaintEventArgs.
Liberando recursos gráficos
Objetos gráficos são caros porque usam recursos do sistema. Esses objetos incluem instâncias da System.Drawing.Graphics classe e instâncias de System.Drawing.Brush, System.Drawing.Pene outras classes gráficas. É importante que você crie um recurso gráfico somente quando precisar dele e libere-o assim que terminar de usá-lo. Se você criar uma instância de um tipo que implementa a IDisposable interface, chame seu Dispose método quando terminar de usá-lo para liberar recursos.
Consulte também
.NET Desktop feedback