Renderowanie formantu formularzy systemu Windows
Renderowanie odnosi się do procesu tworzenia reprezentacji wizualnej na ekranie użytkownika. Formularze systemu Windows używają interfejsu GDI (nowej biblioteki grafiki systemu Windows) do renderowania. Klasy zarządzane, które zapewniają dostęp do interfejsu System.Drawing GDI, znajdują się w przestrzeni nazw i jej podnazwach.
Następujące elementy są zaangażowane w renderowanie kontrolek:
Funkcje rysunku udostępniane przez klasę System.Windows.Forms.Controlbazową .
Podstawowe elementy biblioteki grafiki GDI.
Geometria regionu rysunku.
Procedura zwalniania zasobów graficznych.
Funkcje rysowania udostępniane przez kontrolkę
Klasa Control podstawowa udostępnia funkcje rysowania za pośrednictwem jego Paint zdarzenia. Kontrolka Paint wywołuje zdarzenie za każdym razem, gdy musi zaktualizować jego ekran. Aby uzyskać więcej informacji na temat zdarzeń w programie .NET Framework, zobacz Obsługa i podnoszenie zdarzeń.
Klasa danych zdarzenia dla Paint zdarzenia PaintEventArgs, przechowuje dane potrzebne do rysowania kontrolki — uchwyt do obiektu graficznego i prostokątny obiekt reprezentujący region do rysowania. Te obiekty są wyświetlane pogrubioną czcionką w poniższym fragcie kodu.
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 jest klasą zarządzaną, która hermetyzuje funkcje rysowania, zgodnie z opisem w dalszej części tego tematu. Jest ClipRectangle to wystąpienie Rectangle struktury i definiuje dostępny obszar, w którym kontrolka może rysować. Deweloper kontrolki może obliczyć ClipRectangle przy użyciu ClipRectangle właściwości kontrolki, zgodnie z opisem w dalszej części tego tematu.
Kontrolka musi zapewnić logikę renderowania, przesłaniając metodę OnPaint dziedziczącą z Controlklasy . OnPaint uzyskuje dostęp do obiektu graficznego i prostokąta do rysowania za pomocą Graphics właściwości i ClipRectangle przekazanych PaintEventArgs do niego właściwości wystąpienia.
Protected Overridable Sub OnPaint(pe As PaintEventArgs)
protected virtual void OnPaint(PaintEventArgs pe);
Metoda OnPaint klasy bazowej Control nie implementuje żadnych funkcji rysowania, ale jedynie wywołuje delegatów zdarzeń zarejestrowanych w Paint zdarzeniu. Po zastąpieniu OnPaintmetody zazwyczaj należy wywołać OnPaint metodę klasy bazowej, aby zarejestrowani delegaci otrzymywali Paint zdarzenie. Jednak kontrolki, które malują całą powierzchnię, nie powinny wywoływać klasy bazowej OnPaint, ponieważ wprowadza to migotanie. Aby zapoznać się z przykładem zastąpienia OnPaint zdarzenia, zobacz Instrukcje: tworzenie kontrolki Formularze systemu Windows pokazującej postęp.
Uwaga
Nie należy wywoływać OnPaint bezpośrednio z kontrolki; zamiast tego wywołaj metodę Invalidate (dziedziczona z Controlklasy ) lub inną metodę, która wywołuje Invalidatemetodę . Metoda Invalidate z kolei wywołuje metodę OnPaint. Metoda Invalidate jest przeciążona i, w zależności od argumentów dostarczonych do Invalidate e
, kontrolka ponownie rysuje część lub cały jej obszar ekranu.
Klasa bazowa Control definiuje inną metodę, która jest przydatna OnPaintBackground do rysowania — metody .
Protected Overridable Sub OnPaintBackground(pevent As PaintEventArgs)
protected virtual void OnPaintBackground(PaintEventArgs pevent);
OnPaintBackground maluje tło (a tym samym kształt) okna i gwarantuje szybkość, podczas gdy OnPaint maluje szczegóły i może być wolniejsza, ponieważ poszczególne żądania farby są łączone w jedno Paint zdarzenie, które obejmuje wszystkie obszary, które muszą być ponownie rysowane. Możesz wywołać metodę OnPaintBackground , jeśli na przykład chcesz narysować tło w kolorze gradientu dla kontrolki.
Chociaż OnPaintBackground ma nomenklaturę podobną do zdarzenia i przyjmuje ten sam argument co OnPaint
metoda, OnPaintBackground nie jest to prawdziwa metoda zdarzenia. Brak zdarzenia PaintBackground
i OnPaintBackground nie wywołuje delegatów zdarzeń. Podczas zastępowania OnPaintBackground metody klasa pochodna nie jest wymagana do wywołania OnPaintBackground metody klasy bazowej.
GDI+ Podstawy
Klasa Graphics udostępnia metody rysowania różnych kształtów, takich jak okręgi, trójkąty, łuki i wielokropek, a także metody wyświetlania tekstu. System.Drawing Przestrzeń nazw i jej przestrzenie podrzędne zawierają klasy, które hermetyzują elementy graficzne, takie jak kształty (okręgi, prostokąty, łuki i inne), kolory, czcionki, pędzle itd. Aby uzyskać więcej informacji na temat interfejsu GDI, zobacz Using Managed Graphics Classes (Używanie zarządzanych klas grafiki). Podstawowe elementy interfejsu GDI zostały również opisane w temacie How to: Create a Windows Forms Control That Show Progress (Jak utworzyć kontrolkę Formularzy systemu Windows, która pokazuje postęp).
Geometria regionu rysunku
Właściwość ClientRectangle kontrolki określa prostokątny region dostępny dla kontrolki na ekranie użytkownika, podczas gdy ClipRectangle właściwość PaintEventArgs określa obszar, który jest faktycznie malowany. (Pamiętaj, że malowanie odbywa się w metodzie Paint zdarzenia, która przyjmuje PaintEventArgs wystąpienie jako argument). Kontrolka może wymagać malowania tylko części dostępnego obszaru, tak jak w przypadku zmiany małej części ekranu kontrolki. W takich sytuacjach deweloper kontroli musi obliczyć rzeczywisty prostokąt, aby narysować obiekt i przekazać go do Invalidateelementu . Przeciążone wersje Invalidate elementu , które przyjmują Rectangle argument lub Region jako argument, używają tego argumentu do wygenerowania ClipRectangle właściwości PaintEventArgs.
Poniższy fragment kodu pokazuje, jak FlashTrackBar
kontrolka niestandardowa oblicza prostokątny obszar do narysowania. Zmienna client
określa ClipRectangle właściwość . Pełny przykład można znaleźć w temacie How to: Create a Windows Forms Control That Show Progress (Instrukcje: tworzenie kontrolki formularzy systemu Windows pokazującej postęp).
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)
Zwalnianie zasobów graficznych
Obiekty graficzne są kosztowne, ponieważ używają zasobów systemowych. Takie obiekty obejmują wystąpienia System.Drawing.Graphics klasy, a także wystąpienia System.Drawing.Brushklasy , System.Drawing.Peni innych klas graficznych. Ważne jest, aby utworzyć zasób graficzny tylko wtedy, gdy jest potrzebny i zwolnić go zaraz po zakończeniu korzystania z niego. Jeśli utworzysz typ, który implementuje interfejs, wywołaj jego Dispose metodę po zakończeniu IDisposable pracy z nim, aby zwolnić zasoby.
Poniższy fragment kodu pokazuje, jak kontrolka niestandardowa FlashTrackBar
tworzy i zwalnia Brush zasób. Aby uzyskać pełny kod źródłowy, zobacz Instrukcje: tworzenie kontrolki formularzy systemu Windows, która pokazuje postęp.
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
Zobacz też
.NET Desktop feedback