Malowanie i rysowanie na kontrolkach (Windows Forms .NET)
Niestandardowy obraz kontrolek jest jednym z wielu skomplikowanych zadań ułatwianych przez formularze systemu Windows. Podczas tworzenia kontrolki niestandardowej dostępnych jest wiele opcji obsługi graficznego wyglądu kontrolki. Jeśli tworzysz kontrolkę niestandardową, oznacza to, że kontrolka dziedzicząca z Controlelementu , musisz podać kod, aby renderować jego graficzną reprezentację.
Jeśli tworzysz kontrolkę złożoną, to jest to kontrolka dziedziczona z UserControl lub jednej z istniejących kontrolek Windows Forms, możesz zastąpić standardową graficzną reprezentację i podać własny kod graficzny.
Jeśli chcesz udostępnić renderowanie niestandardowe dla istniejącej kontrolki bez tworzenia nowej kontrolki, opcje stają się bardziej ograniczone. Jednak nadal istnieje wiele możliwości graficznych dla kontrolek i aplikacji.
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.
Rysunek dostarczony 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ń na platformie .NET, zobacz Obsługa i zgłaszanie zdarzeń.
Klasa danych zdarzenia dla Paint zdarzenia PaintEventArgs, przechowuje dane potrzebne do rysowania kontrolki — uchwyt do obiektu graficznego i prostokąt reprezentujący region do rysowania.
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 jest klasą zarządzaną, która hermetyzuje funkcje rysowania, zgodnie z opisem w dalszej części tego artykułu. 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 artykułu.
OnPaint
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.
Poniższy kod używa System.Drawing
przestrzeni nazw:
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
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.
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
, ponownie rysuje część lub cały jej obszar ekranu.
Kod w OnPaint metodzie kontrolki zostanie wykonany po pierwszym narysowanym kontrolce i za każdym razem, gdy zostanie odświeżony. Aby upewnić się, że kontrolka jest ponownie rysowana przy każdej zmianie rozmiaru, dodaj następujący wiersz do konstruktora kontrolki:
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)
OnPaintBackground
Klasa bazowa Control definiuje inną metodę, która jest przydatna OnPaintBackground do rysowania metody .
protected virtual void OnPaintBackground(PaintEventArgs e);
Protected Overridable Sub OnPaintBackground(e As PaintEventArgs)
OnPaintBackground maluje tło (i w ten sposób kształt) okna i gwarantuje szybkość, podczas gdy OnPaint maluje szczegóły i może być wolniejsze, 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 oraz metody wyświetlania tekstu. System.Drawing Przestrzeń nazw zawiera przestrzenie nazw i klasy, które hermetyzują elementy graficzne, takie jak kształty (okręgi, prostokąty, łuki i inne), kolory, czcionki, pędzle itd.
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 malowany. 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.
Zwalnianie zasobów graficznych
Obiekty graficzne są kosztowne, ponieważ używają zasobów systemowych. Takie obiekty obejmują wystąpienia System.Drawing.Graphics klasy i wystąpień 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 wystąpienie typu implementujące interfejs, wywołaj jego Dispose metodę po zakończeniu IDisposable pracy z nim, aby zwolnić zasoby.
Zobacz też
.NET Desktop feedback