Vykreslení ovládacího prvku Windows Forms

Vykreslování odkazuje na proces vytvoření vizuální reprezentace na obrazovce uživatele. model Windows Forms k vykreslování používá GDI (novou grafickou knihovnu Windows). Spravované třídy, které poskytují přístup k GDI, jsou v System.Drawing oboru názvů a jeho podnázvových prostorech.

Vykreslování ovládacích prvků se týká následujících prvků:

  • Funkce kreslení poskytované základní třídou System.Windows.Forms.Control.

  • Základní prvky grafické knihovny GDI.

  • Geometrie oblasti výkresu.

  • Postup uvolnění grafických prostředků.

Funkce kreslení poskytované ovládacím prvek

Základní třída Control poskytuje funkce kreslení prostřednictvím své Paint události. Ovládací prvek vyvolá Paint událost pokaždé, když potřebuje aktualizovat zobrazení. Další informace o událostech v rozhraní .NET Framework naleznete v tématu Zpracování a vyvolávání událostí.

Datová třída Paint události události PaintEventArgsobsahuje data potřebná pro kreslení ovládacího prvku – popisovač grafického objektu a obdélníkový objekt, který představuje oblast, do které se má nakreslit. Tyto objekty jsou zobrazeny tučně v následujícím fragmentu kódu.

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 je spravovaná třída, která zapouzdřuje funkce kreslení, jak je popsáno v diskuzi O GDI dále v tomto tématu. Jedná se ClipRectangle o instanci Rectangle struktury a definuje dostupnou oblast, ve které může ovládací prvek kreslit. Vývojář ovládacího prvku může vypočítat ClipRectangle použití ClipRectangle vlastnosti ovládacího prvku, jak je popsáno v diskuzi o geometrii dále v tomto tématu.

Ovládací prvek musí poskytovat logiku vykreslování přepsáním OnPaint metody, ze které dědí .Control OnPaint získá přístup k grafickému objektu a obdélník, který se má nakreslit přes GraphicsClipRectangle vlastnosti instance předané do objektu PaintEventArgs .

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

Metoda OnPaint základní Control třídy neimplementuje žádné funkce výkresu, ale pouze vyvolá delegáty událostí, které jsou registrovány v Paint události. Při přepsání OnPaintbyste obvykle měli vyvolat OnPaint metodu základní třídy, aby registrovaní delegáti obdrželi Paint událost. Ovládací prvky, které malují celý povrch, by však neměly vyvolat základní třídu OnPaint, protože to představuje blikající. Příklad přepsání OnPaint události najdete v části Postupy: Vytvoření ovládacího prvku model Windows Forms, který zobrazuje průběh.

Poznámka:

Nevyvolejte OnPaint přímo z vašeho ovládacího prvku; místo toho volejte metodu Invalidate (zděděnou z Control) nebo jinou metodu, která vyvolá Invalidate. Metoda Invalidate zase vyvolá OnPaint. Metoda Invalidate je přetížena a v závislosti na argumentech zadaných do Invalidateeovládacího prvku překreslí některé nebo všechny jeho oblasti obrazovky.

Základní Control třída definuje jinou metodu, která je užitečná pro kreslení – metodu OnPaintBackground .

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

OnPaintBackground maluje pozadí (a tím tvar) okna a je zaručeno, že je rychlé, zatímco OnPaint maluje detaily a může být pomalejší, protože jednotlivé požadavky na malování jsou sloučeny do jedné Paint události, která pokrývá všechny oblasti, které musí být překresleny. Můžete například chtít vyvolat OnPaintBackground , pokud chcete pro ovládací prvek nakreslit barevné pozadí s přechodem.

I když OnPaintBackground má terminologii podobná událostem a používá stejný argument jako OnPaint metoda, OnPaintBackground není to skutečná metoda události. Neexistuje žádná PaintBackground událost a OnPaintBackground nevyvolá delegáty událostí. Při přepsání OnPaintBackground metody není odvozená třída nutná k vyvolání OnPaintBackground metody její základní třídy.

Základy GDI+

Třída Graphics poskytuje metody pro kreslení různých obrazců, jako jsou kruhy, trojúhelníky, oblouky a tři tečky, stejně jako metody pro zobrazení textu. System.Drawing Obor názvů a jeho podnázvové prostory obsahují třídy, které zapouzdřují grafické prvky, jako jsou obrazce (kruhy, obdélníky, oblouky a další), barvy, písma, štětce atd. Další informace o GDI naleznete v tématu Použití spravovaných grafických tříd. Základy GDI jsou popsány také v části Postupy: Vytvoření ovládacího prvku model Windows Forms, který ukazuje průběh.

Geometrie oblasti výkresu

Vlastnost ClientRectangle ovládacího prvku určuje obdélníkovou oblast dostupnou pro ovládací prvek na obrazovce uživatele, zatímco ClipRectangle vlastnost PaintEventArgs určuje oblast, která je skutečně vykreslena. (Mějte na paměti, že obraz se provádí v Paint metodě události, která přebírá PaintEventArgs instanci jako svůj argument). Ovládací prvek může potřebovat nakreslit jenom část jeho dostupné oblasti, stejně jako v případě, že se změní malá část zobrazení ovládacího prvku. V těchto situacích musí vývojář ovládacího prvku vypočítat skutečný obdélník, aby se nakreslil a předal ho Invalidate. Přetížené verze Invalidate , které přebírají Rectangle nebo Region jako argument používají tento argument k vygenerování ClipRectangle vlastnosti PaintEventArgs.

Následující fragment kódu ukazuje, jak FlashTrackBar vlastní ovládací prvek vypočítá obdélníkovou oblast, do které se má nakreslit. Proměnná client označuje ClipRectangle vlastnost. Kompletní ukázku najdete v tématu Postupy: Vytvoření ovládacího prvku model Windows Forms, který zobrazuje průběh.

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)

Uvolnění grafických prostředků

Grafické objekty jsou nákladné, protože používají systémové prostředky. Takové objekty zahrnují instance System.Drawing.Graphics třídy, stejně jako instance System.Drawing.Brush, System.Drawing.Pena další grafické třídy. Je důležité, abyste vytvořili grafický prostředek pouze v případě, že ho potřebujete, a jakmile ho budete používat, uvolněte ho. Pokud vytvoříte typ, který implementuje IDisposable rozhraní, zavolejte jeho Dispose metodu po dokončení s ním, aby se uvolnily prostředky.

Následující fragment kódu ukazuje, jak FlashTrackBar vlastní ovládací prvek vytvoří a uvolní Brush prostředek. Úplný zdrojový kód najdete v tématu Postupy: Vytvoření ovládacího prvku model Windows Forms, který zobrazuje průběh.

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

Viz také