Renderizando um controle dos Windows Forms
Renderização se refere ao processo de criar uma representação visual na tela do usuário. O Windows Forms usa GDI (a nova biblioteca de elementos gráficos do Windows) para renderização. As classes gerenciadas que fornecem acesso ao GDI estão no System.Drawing namespace e em seus subnamespaces.
Os elementos a seguir estão envolvidos na renderização de controles:
A funcionalidade de desenho fornecida pela classe System.Windows.Forms.Controlbase .
Os elementos essenciais da biblioteca gráfica GDI.
A geometria da região de desenho.
O procedimento para liberar recursos gráficos.
Funcionalidade de desenho fornecida pelo controle
A classe Control base fornece funcionalidade de desenho por meio de seu Paint evento. Um controle aciona o Paint evento sempre que ele precisa atualizar sua exibição. Para obter mais informações sobre os eventos no .NET Framework, consulte Tratando e gerando eventos.
A classe de dados do evento para o Paint evento, , PaintEventArgscontém os dados necessários para desenhar um controle — um identificador para um objeto gráfico e um objeto retangular que representa a região a ser desenhada. Esses objetos são mostrados em negrito no seguinte fragmento de código.
Public Class PaintEventArgs
Inherits EventArgs
Implements IDisposable
Public ReadOnly Property ClipRectangle() As System.Drawing.Rectangle
...
End Property
Public ReadOnly Property Graphics() As System.Drawing.Graphics
...
End Property
' Other properties and methods.
...
End Class
public class PaintEventArgs : EventArgs, IDisposable {
public System.Drawing.Rectangle ClipRectangle {get;}
public System.Drawing.Graphics Graphics {get;}
// Other properties and methods.
...
}
Graphics é uma classe gerenciada que encapsula a funcionalidade de desenho, conforme descrito na discussão do GDI mais adiante neste tópico. 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 uso ClipRectangle da propriedade de um controle, conforme descrito na discussão de geometria mais adiante neste tópico.
Um controle deve fornecer lógica de renderização substituindo o OnPaint método que ele herda do Control. OnPaint Obtém acesso a um objeto gráfico e a um retângulo para desenhar através das Graphics propriedades e da ClipRectanglePaintEventArgs instância passada para ele.
Protected Overridable Sub OnPaint(pe As PaintEventArgs)
protected virtual void OnPaint(PaintEventArgs pe);
O OnPaint método da classe base Control não implementa nenhuma funcionalidade de desenho, mas apenas invoca os delegados de evento que estão registrados com o Paint evento. Ao substituir OnPainto , você normalmente deve invocar o OnPaint método da classe base para que os delegados registrados recebam o Paint evento. No entanto, os controles que pintam toda a superfície não devem invocar a classe OnPaintbase, pois isso introduz a cintilação. Para obter um exemplo de substituição do evento, consulte Como: Criar um controle do Windows Forms que mostra o OnPaintprogresso.
Observação
Não invoque diretamente do seu controle, em vez disso, invoque o método (herdado de Control) ou algum outro método que invoque OnPaintInvalidate.Invalidate O Invalidate método, por sua vez, OnPaintinvoca . O Invalidate método é sobrecarregado e, dependendo dos argumentos fornecidos ao Invalidatee
, um controle redesenha parte ou toda a sua área de tela.
A classe base Control define outro método que é útil para desenhar — o OnPaintBackground método.
Protected Overridable Sub OnPaintBackground(pevent As PaintEventArgs)
protected virtual void OnPaintBackground(PaintEventArgs pevent);
OnPaintBackground pinta o fundo (e, portanto, a forma) da janela e é garantido que seja 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 abrange todas as áreas que precisam ser redesenhadas. Talvez você queira invocar o OnPaintBackground se, por exemplo, você deseja desenhar um plano de fundo colorido de gradiente para seu controle.
Embora OnPaintBackground tenha uma nomenclatura semelhante a um evento e tenha 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 método, uma classe derivada não é necessária para invocar o OnPaintBackgroundOnPaintBackground 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, bem como métodos para exibir texto. O System.Drawing namespace e seus subnamespaces contêm classes que encapsulam elementos gráficos, como formas (círculos, retângulos, arcos e outros), cores, fontes, pincéis e assim por diante. Para obter mais informações sobre GDI, consulte Usando classes de gráficos gerenciados. Os fundamentos do GDI também são descritos em Como: Criar um controle do Windows Forms que mostra o progresso.
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 propriedade de PaintEventArgs especifica a ClipRectangle área que é realmente pintada. (Lembre-se de que a Paint pintura é feita no método de evento que toma uma PaintEventArgs instância como argumento). 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 controle deve calcular o retângulo real para desenhar e passar isso para Invalidate. As versões sobrecarregadas Invalidate que usam um ou Region como um Rectangle argumento usam esse argumento para gerar a ClipRectangle propriedade de PaintEventArgs.
O fragmento de código a seguir mostra como o controle personalizado FlashTrackBar
calcula a área retangular na qual desenhar. A client
variável denota a ClipRectangle propriedade. Para ver um exemplo completo, consulte Como criar um controle do Windows Forms que mostre o progresso.
Rectangle invalid = new Rectangle(
client.X + min,
client.Y,
max - min,
client.Height);
Invalidate(invalid);
Dim invalid As Rectangle = New Rectangle( _
client.X + lmin, _
client.Y, _
lmax - lmin, _
client.Height)
Invalidate(invalid)
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, bem como instâncias de , System.Drawing.Pene outras classes gráficasSystem.Drawing.Brush. É importante que você crie um recurso de gráfico somente quando precisar dele e o libere assim que terminar de usá-lo. Se você criar um tipo que implementa a IDisposable interface, chame seu Dispose método quando terminar de usá-lo para liberar recursos.
O fragmento de código a seguir mostra como o FlashTrackBar
controle personalizado cria e libera um Brush recurso. Para ver o código-fonte completo, consulte Como criar um controle do Windows Forms que mostre o progresso.
private Brush baseBackground = null;
Private baseBackground As Brush
base.OnPaint(e);
if (baseBackground == null) {
if (showGradient) {
baseBackground = new LinearGradientBrush(new Point(0, 0),
new Point(ClientSize.Width, 0),
StartColor,
EndColor);
}
else if (BackgroundImage != null) {
baseBackground = new TextureBrush(BackgroundImage);
}
else {
baseBackground = new SolidBrush(BackColor);
}
}
MyBase.OnPaint(e)
If (baseBackground Is Nothing) Then
If (myShowGradient) Then
baseBackground = New LinearGradientBrush(New Point(0, 0), _
New Point(ClientSize.Width, 0), _
StartColor, _
EndColor)
ElseIf (BackgroundImage IsNot Nothing) Then
baseBackground = New TextureBrush(BackgroundImage)
Else
baseBackground = New SolidBrush(BackColor)
End If
End If
protected override void OnResize(EventArgs e) {
base.OnResize(e);
if (baseBackground != null) {
baseBackground.Dispose();
baseBackground = null;
}
}
Protected Overrides Sub OnResize(ByVal e As EventArgs)
MyBase.OnResize(e)
If (baseBackground IsNot Nothing) Then
baseBackground.Dispose()
baseBackground = Nothing
End If
End Sub
Confira também
.NET Desktop feedback
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de