Freigeben über


Wiedergeben eines Windows Forms-Steuerelements

Als Rendering wird ein Prozess bezeichnet, durch den eine visuelle Repräsentation auf dem Bildschirm eines Benutzers erzeugt wird. Windows Forms verwendet zum Rendern GDI (die neue Windows-Graphikbibliothek). Die verwalteten Klassen, die den Zugriff auf GDI ermöglichen, befinden sich im System.Drawing-Namespace und in dessen untergeordneten Namespaces.

Die folgenden Elemente spielen beim Rendern von Steuerelementen eine Rolle:

  • Die Zeichnungsfunktionalität, die von der System.Windows.Forms.Control-Basisklasse bereitgestellt wird.

  • Die wichtigsten Elemente der GDI-Graphikbibliothek.

  • Die Geometrie des Bereichs, in dem gezeichnet wird.

  • Das Verfahren, mit dem Graphikressourcen freigegeben werden.

Vom Steuerelement bereitgestellte Zeichnungsfunktionen

Die Control-Basisklasse stellt über das Paint-Ereignis Zeichnungsfunktionalität bereit. Ein Steuerelement löst das Paint-Ereignis immer dann aus, wenn seine Anzeige aktualisiert werden muss. Weitere Informationen über Ereignisse in .NET Framework finden Sie unter Behandeln und Auslösen von Ereignissen.

Die Ereignisdatenklasse für das Paint-Ereignis, PaintEventArgs, beinhaltet die Daten, die für das Zeichnen des Steuerelements benötigt werden – ein Handle eines Graphikobjekts und ein rechteckiges Objekt, das den Bereich darstellt, in dem gezeichnet wird. Diese Objekte sind im folgenden Codefragment fett dargestellt.

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 ist eine verwaltete Klasse, die Zeichnungsfunktionen kapselt. Dies wird im Abschnitt zu GDI weiter unten in diesem Thema beschrieben. ClipRectangle ist eine Instanz der Rectangle-Struktur und definiert den verfügbaren Bereich, in dem ein Steuerelement zeichnen kann. Der Entwickler eines Steuerelements kann ClipRectangle mithilfe der ClipRectangle-Eigenschaft eines Steuerelements berechnen. Dies wird weiter unten im Abschnitt zur Geometrie beschrieben.

Ein Steuerelement muss Renderlogik bereitstellen, indem die OnPaint-Methode, die es von Control erbt, überschrieben wird. OnPaint erhält mithilfe der Graphics-Eigenschaft und der ClipRectangle-Eigenschaft der übergebenen PaintEventArgs-Instanz Zugriff auf ein Graphikobjekt und ein Rechteck, in dem gezeichnet werden soll.

Protected Overridable Sub OnPaint(pe As PaintEventArgs)
protected virtual void OnPaint(PaintEventArgs pe);

Die OnPaint-Methode der Basisklasse von Control implementiert keine Zeichnungsfunktionen, sondern ruft lediglich die Ereignisdelegaten auf, die mit dem Paint-Ereignis registriert sind. Beim Überschreiben von OnPaint sollten Sie im Normalfall die OnPaint-Methode der Basisklasse aufrufen, sodass registrierte Delegaten das Paint-Ereignis empfangen. Allerdings sollten Steuerelemente, die ihre gesamte Oberfläche zeichnen, nicht die OnPaint-Methode der Basisklasse aufrufen, um Flimmern zu vermeiden. Ein Beispiel zum Überschreiben des OnPaint-Ereignisses finden Sie unter Gewusst wie: Erstellen eines Windows Forms-Steuerelements, das den Fortschritt anzeigt.

Tipp

Rufen Sie OnPaint nicht direkt über das Steuerelement auf, sondern über die von Control geerbte Invalidate-Methode oder eine andere Methode, die Invalidate aufruft. Die Invalidate-Methode ruft wiederum OnPaint auf. Die Invalidate-Methode wird überladen. Ein Steuerelement zeichnet abhängig von den für Invalidate angegebenen Argumenten seinen Bildschirmbereich teilweise oder vollständig neu.

Durch die Basisklasse von Control wird eine andere Methode definiert, die für das Zeichnen von Nutzen ist: die OnPaintBackground-Methode.

Protected Overridable Sub OnPaintBackground(pevent As PaintEventArgs)
protected virtual void OnPaintBackground(PaintEventArgs pevent);

Mit OnPaintBackground wird der Hintergrund (und dadurch auch die Form) des Fensters gezeichnet und schnelles Vorgehen gewährleistet. Dagegen dient OnPaint dem Zeichnen von Details, wodurch diese Methode langsamer ist, da einzelne Anforderungen zum Zeichnen in einem Paint-Ereignis zusammengefasst werden, das alle erneut zu zeichnenden Bereiche abdeckt. Sie können OnPaintBackground z. B. dann aufrufen, wenn Sie für das Steuerelement einen Hintergrund mit Farbverlauf zeichnen möchten.

Obwohl OnPaintBackground Bezeichnungen verwendet, die der einer Ereignismethode ähnlich sind, und sie dasselbe Argument wie die OnPaint-Methode unterstützt, ist OnPaintBackground dennoch keine Ereignismethode. Es gibt kein PaintBackground-Ereignis, und von OnPaintBackground werden keine Ereignisdelegaten aufgerufen. Beim Überschreiben der OnPaintBackground-Methode ist es nicht notwendig, dass die abgeleitete Klasse die OnPaintBackground-Methode ihrer Basisklasse aufruft.

Grundlagen von GDI+

Die Graphics-Klasse stellt Methoden zum Zeichnen verschiedener Formen, z. B. von Kreisen, Dreiecken, Bögen und Ellipsen, sowie Methoden zum Anzeigen von Text zur Verfügung. Der System.Drawing-Namespace und seine untergeordneten Namespaces enthalten Klassen, die grafische Elemente wie Formen (Kreise, Rechtecke, Bögen u. a.), Farben, Schriftarten, Pinsel usw. umfassen. Weitere Informationen zu GDI finden Sie unter Verwenden von verwalteten Grafikklassen. Die wichtigsten Aspekte von GDI werden zudem unter Gewusst wie: Erstellen eines Windows Forms-Steuerelements, das den Fortschritt anzeigt beschrieben.

Geometrie des Zeichenbereichs

Die ClientRectangle-Eigenschaft eines Steuerelements legt den rechteckigen Bereich fest, der für das Steuerelement auf dem Bildschirm des Benutzers verfügbar ist, während die ClipRectangle-Eigenschaft von PaintEventArgs den Bereich festlegt, der tatsächlich gezeichnet wird. (Beachten Sie, dass das Zeichnen durch die Paint-Ereignismethode erfolgt, die eine PaintEventArgs-Instanz als Argument verwendet). Ein Steuerelement muss seinen verfügbaren Bereich möglicherweise nur teilweise zeichnen, z. B. dann, wenn nur ein kleiner Ausschnitt des angezeigten Steuerelements geändert wird. In solchen Fällen muss der Entwickler des Steuerelements das tatsächlich zu zeichnende Rechteck berechnen und es an Invalidate weitergeben. Die überladenen Versionen von Invalidate, die ein Rectangle oder einen Region als Argument verwenden, generieren hiermit die ClipRectangle-Eigenschaft von PaintEventArgs.

Im folgenden Codefragment wird gezeigt, wie das benutzerdefinierte Steuerelement FlashTrackBar den rechteckigen Bereich berechnet, in dem gezeichnet werden soll. Die client-Variable kennzeichnet die ClipRectangle-Eigenschaft. Ein vollständiges Beispiel finden Sie unter Gewusst wie: Erstellen eines Windows Forms-Steuerelements, das den Fortschritt anzeigt.

Dim invalid As Rectangle = New Rectangle( _
    client.X + lmin, _
    client.Y, _
    lmax - lmin, _
    client.Height)

Invalidate(invalid)
Rectangle invalid = new Rectangle(
    client.X + min, 
    client.Y, 
    max - min, 
    client.Height);

Invalidate(invalid);

Freigeben von Graphikressourcen

Die Verwendung graphischer Objekte ist aufwendig, da diese Systemressourcen verwenden. Zu diesen Objekten gehören Instanzen der System.Drawing.Graphics-Klasse sowie Instanzen von System.Drawing.Brush, System.Drawing.Pen und anderen Graphikklassen. Es ist wichtig, dass Sie eine graphische Ressource nur bei Bedarf erstellen und diese wieder freigeben, sobald sie nicht mehr verwendet wird. Wenn Sie einen Typ erstellen, der die IDisposable-Schnittstelle implementiert, rufen Sie seine Dispose-Methode auf, sobald er nicht mehr verwendet wird, um Ressourcen freizugeben.

Im folgendem Codefragment wird gezeigt, wie durch das benutzerdefinierte FlashTrackBar-Steuerelement eine Brush-Ressource erstellt und wieder freigegeben wird. Den vollständigen Quellcode finden Sie unter Gewusst wie: Erstellen eines Windows Forms-Steuerelements, das den Fortschritt anzeigt.

Private baseBackground As Brush
private Brush baseBackground = null;
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
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);
    }
}
Protected Overrides Sub OnResize(ByVal e As EventArgs)
    MyBase.OnResize(e)
    If (baseBackground IsNot Nothing) Then
        baseBackground.Dispose()
        baseBackground = Nothing
    End If
End Sub
protected override void OnResize(EventArgs e) {
    base.OnResize(e);
    if (baseBackground != null) {
        baseBackground.Dispose();
        baseBackground = null;
    }
}

Siehe auch

Aufgaben

Gewusst wie: Erstellen eines Windows Forms-Steuerelements, das den Fortschritt anzeigt