Malování a kreslení na ovládacích prvcích (model Windows Forms .NET)

Vlastní malování ovládacích prvků je jedním z mnoha složitých úkolů, které model Windows Forms usnadňují. Při vytváření vlastního ovládacího prvku máte k dispozici řadu možností pro zpracování grafického vzhledu ovládacího prvku. Pokud autorujete vlastní ovládací prvek, tedy ovládací prvek, který dědí z Control, musíte zadat kód pro vykreslení jeho grafické reprezentace.

Pokud vytváříte složený ovládací prvek, jedná se o ovládací prvek, který dědí z UserControl existujícího model Windows Forms ovládacích prvků, můžete přepsat standardní grafické znázornění a poskytnout vlastní grafický kód.

Pokud chcete poskytnout vlastní vykreslování existujícího ovládacího prvku bez vytvoření nového ovládacího prvku, budou vaše možnosti omezenější. Existuje však celá řada grafických možností pro vaše ovládací prvky a aplikace.

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ů.

Výkres poskytnutý 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 naleznete v tématu Zpracování a vyvolávání událostí.

Datová třída události události Paint obsahuje PaintEventArgsdata potřebná k vykreslení ovládacího prvku – popisovač grafického objektu a obdélník, který představuje oblast, do které se má kreslit.

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 je spravovaná třída, která zapouzdřuje funkce kreslení, jak je popsáno v diskuzi O GDI dále v tomto článku. 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 článku.

OnPaint

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 Graphics ClipRectangle vlastnosti instance předané do objektu PaintEventArgs .

Následující kód používá System.Drawing obor názvů:

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 základní Control třídy neimplementuje žádné funkce kreslení, ale pouze vyvolá delegáty událostí, které jsou registrovány událostí Paint . 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í.

Poznámka:

Nevyvolejte OnPaint přímo z 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 Invalidate e, překreslí některé nebo všechny jeho oblasti obrazovky.

Kód v OnPaint metodě vašeho ovládacího prvku se spustí při prvním vykreslení ovládacího prvku a při každé aktualizaci. Pokud chcete zajistit, aby byl ovládací prvek při každé změně velikosti překreslen, přidejte do konstruktoru ovládacího prvku následující řádek:

SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)

OnPaintBackground

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

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

OnPaintBackground maluje pozadí (a tímto způsobem tvar) okna a je zaručeno, že je rychlé, zatímco OnPaint maluje detaily a může být pomalejší, protože jednotlivé žádosti o 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 kreslení různých obrazců, jako jsou kruhy, trojúhelníky, oblouky a tři tečky a metody pro zobrazení textu. System.Drawing Obor názvů obsahuje obory názvů a třídy, které zapouzdřují grafické prvky, jako jsou obrazce (kruhy, obdélníky, oblouky a další), barvy, písma, štětce atd.

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 vykreslena. 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.

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 a instance System.Drawing.Brush, System.Drawing.Pena další grafické třídy. Je důležité, abyste vytvořili grafický prostředek jenom v případě, že ho potřebujete, a jakmile ho budete používat, uvolněte ho. Pokud vytvoříte instanci typu, který implementuje IDisposable rozhraní, zavolejte její Dispose metodu, jakmile s ní budete hotovi, uvolnit prostředky.

Viz také