Freigeben über


Verwenden geschachtelter Grafikcontainer

GDI+ stellt Container bereit, mit denen Sie Teile des in einem Graphics-Objekt festgelegten Zustands vorübergehend ersetzen oder erweitern können. Sie erstellen einen Container, indem Sie die BeginContainer-Methode eines Graphics-Objekts aufrufen. BeginContainer kann wiederholt aufgerufen werden, um geschachtelte Container zu erstellen. Jeder Aufruf von BeginContainer muss mit einem entsprechenden Aufruf von EndContainer abgeschlossen werden.

Transformationen in geschachtelten Containern

Im folgenden Beispiel werden ein Graphics-Objekt und ein Container innerhalb dieses Graphics-Objekts erstellt. Die globale Transformation des Graphics-Objekts entspricht einer Verschiebung von 100 Einheiten in x-Richtung und 80 Einheiten in y-Richtung. Die globale Transformation des Containers entspricht einer Drehung um 30 Grad. Der Aufruf DrawRectangle(pen, -60, -30, 120, 60) wird vom Code zweimal ausgeführt. Der erste Aufruf von DrawRectangle erfolgt innerhalb des Containers, er findet also zwischen den Aufrufen von BeginContainer und EndContainer statt. Der zweite Aufruf von DrawRectangle erfolgt nach dem Aufruf von EndContainer.

        Dim graphics As Graphics = e.Graphics
        Dim pen As New Pen(Color.Red)
        Dim graphicsContainer As GraphicsContainer
        graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3)

        graphics.TranslateTransform(100, 80)

        graphicsContainer = graphics.BeginContainer()
        graphics.RotateTransform(30)
        graphics.DrawRectangle(pen, -60, -30, 120, 60)
        graphics.EndContainer(graphicsContainer)

        graphics.DrawRectangle(pen, -60, -30, 120, 60)

Graphics graphics = e.Graphics;
Pen pen = new Pen(Color.Red);
GraphicsContainer graphicsContainer;
graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3);

graphics.TranslateTransform(100, 80);

graphicsContainer = graphics.BeginContainer();
graphics.RotateTransform(30);
graphics.DrawRectangle(pen, -60, -30, 120, 60);
graphics.EndContainer(graphicsContainer);

graphics.DrawRectangle(pen, -60, -30, 120, 60);

Im vorangehenden Code wird das aus dem Container heraus gezeichnete Rechteck zunächst durch die globale Transformation des Containers (Drehung) und anschließend durch die globale Transformation des Graphics-Objekts (Verschiebung) transformiert. Auf das außerhalb des Containers gezeichnete Rechteck wird lediglich die globale Transformation des Graphics-Objekts (Verschiebung) angewendet. In der folgenden Abbildung sind die beiden Rechtecke dargestellt.

Geschachtelte Container

Clipping in geschachtelten Containern

Im folgenden Beispiel wird veranschaulicht, wie Clippingbereiche von geschachtelten Containern behandelt werden. Im Code werden ein Graphics-Objekt und ein Container innerhalb dieses Graphics-Objekts erstellt. Der Clippingbereich des Graphics-Objekts ist ein Rechteck und der des Containers eine Ellipse. Der Code führt zwei DrawLine-Methodenaufrufe aus. Der erste Aufruf von DrawLine erfolgt innerhalb und der zweite Aufruf von DrawLine außerhalb des Containers (nach dem Aufruf von EndContainer). Die erste Linie wird abgeschnitten, da sich die beiden Clippingbereiche schneiden. Die zweite Linie wird nur durch den rechteckigen Clippingbereich des Graphics-Objekts abgeschnitten.

        Dim graphics As Graphics = e.Graphics
        Dim graphicsContainer As GraphicsContainer
        Dim redPen As New Pen(Color.Red, 2)
        Dim bluePen As New Pen(Color.Blue, 2)
        Dim aquaBrush As New SolidBrush(Color.FromArgb(255, 180, 255, 255))
        Dim greenBrush As New SolidBrush(Color.FromArgb(255, 150, 250, 130))

        graphics.SetClip(New Rectangle(50, 65, 150, 120))
        graphics.FillRectangle(aquaBrush, 50, 65, 150, 120)

        graphicsContainer = graphics.BeginContainer()
        ' Create a path that consists of a single ellipse.
        Dim path As New GraphicsPath()
        path.AddEllipse(75, 50, 100, 150)

        ' Construct a region based on the path.
        Dim [region] As New [Region](path)
        graphics.FillRegion(greenBrush, [region])

        graphics.SetClip([region], CombineMode.Replace)
        graphics.DrawLine(redPen, 50, 0, 350, 300)
        graphics.EndContainer(graphicsContainer)

        graphics.DrawLine(bluePen, 70, 0, 370, 300)

Graphics graphics = e.Graphics;
GraphicsContainer graphicsContainer;
Pen redPen = new Pen(Color.Red, 2);
Pen bluePen = new Pen(Color.Blue, 2);
SolidBrush aquaBrush = new SolidBrush(Color.FromArgb(255, 180, 255, 255));
SolidBrush greenBrush = new SolidBrush(Color.FromArgb(255, 150, 250, 130));

graphics.SetClip(new Rectangle(50, 65, 150, 120));
graphics.FillRectangle(aquaBrush, 50, 65, 150, 120);

graphicsContainer = graphics.BeginContainer();
// Create a path that consists of a single ellipse.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(75, 50, 100, 150);

// Construct a region based on the path.
Region region = new Region(path);
graphics.FillRegion(greenBrush, region);

graphics.SetClip(region, CombineMode.Replace);
graphics.DrawLine(redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);

graphics.DrawLine(bluePen, 70, 0, 370, 300);

In der folgenden Abbildung sind die beiden abgeschnittenen Linien dargestellt.

Geschachtelter Container

Aus den beiden vorherigen Beispielen ist ersichtlich, dass Transformationen und Clippingbereiche in geschachtelten Containern kumulativ sind. Wenn Sie die globalen Transformationen von Container und Graphics-Objekt festlegen, werden auf die aus dem Container heraus gezeichneten Elemente beide Transformationen angewendet. Zuerst wird die Transformation des Containers und anschließend die Transformation des Graphics-Objekts angewendet. Wenn Sie sowohl den Clippingbereich des Containers als auch den des Graphics-Objekts definieren, werden die aus dem Container heraus gezeichneten Elemente abgeschnitten, da die beiden Clippingbereiche einander schneiden.

Qualitätseinstellungen in geschachtelten Containern

Qualitätseinstellungen (SmoothingMode, TextRenderingHint u. ä.) in geschachtelten Containern sind nicht kumulativ. Vielmehr werden die Qualitätseinstellungen eines Graphics-Objekts temporär durch die Qualitätseinstellungen des Containers ersetzt. Wenn Sie einen neuen Container erstellen, werden als Qualitätseinstellungen für diesen Container Standardwerte festgelegt. Angenommen, bei einem Graphics-Objekt wurde für den Glättungsmodus AntiAlias festgelegt. Wenn Sie einen Container erstellen, wird der Glättungsmodus innerhalb des Containers automatisch zum Standardmodus. Der Glättungsmodus des Containers kann beliebig festgelegt werden, und alle aus dem Container heraus gezeichneten Elemente werden entsprechend diesem Modus gezeichnet. Auf Elemente, die nach dem Aufruf von EndContainer gezeichnet werden, wird der Glättungsmodus (AntiAlias) angewendet, der vor dem Aufruf von BeginContainer gültig war.

Auf mehreren Ebenen geschachtelte Container

In einem Graphics-Objekt können mehrere Container geschachtelt werden. Sie können eine Abfolge von Containern erstellen, wobei jeder in seinem Vorgänger geschachtelt ist. Außerdem können globale Transformation, Clippingbereich und Qualitätseinstellungen jedes einzelnen Containers festgelegt werden. Wenn Sie eine Zeichenmethode aus dem innersten Container aufrufen, werden die Transformationen in der entsprechenden Reihenfolge angewendet, also beginnend beim innersten Container bis hin zum äußersten Container. Elemente, die aus dem innersten Container gezeichnet werden, werden dort abgeschnitten, wo sich die Clippingbereiche schneiden.

Im folgenden Beispiel wird ein Graphics-Objekt erstellt und sein TextRenderingHint auf AntiAlias festgelegt. Durch den Code werden zwei Container erstellt, die ineinander geschachtelt sind. Der TextRenderingHint des äußeren Containers ist auf SingleBitPerPixel und der des inneren Containers auf AntiAlias festgelegt. Durch den Code werden drei Zeichenfolgen gezeichnet: eine aus dem inneren Container, eine aus dem äußeren Container und eine dritte aus dem Graphics-Objekt selbst.

        Dim graphics As Graphics = e.Graphics
        Dim innerContainer As GraphicsContainer
        Dim outerContainer As GraphicsContainer
        Dim brush As New SolidBrush(Color.Blue)
        Dim fontFamily As New FontFamily("Times New Roman")
        Dim font As New Font( _
           fontFamily, _
           36, _
           FontStyle.Regular, _
           GraphicsUnit.Pixel)

        graphics.TextRenderingHint = _
        System.Drawing.Text.TextRenderingHint.AntiAlias

        outerContainer = graphics.BeginContainer()

        graphics.TextRenderingHint = _
            System.Drawing.Text.TextRenderingHint.SingleBitPerPixel

        innerContainer = graphics.BeginContainer()
        graphics.TextRenderingHint = _
            System.Drawing.Text.TextRenderingHint.AntiAlias
        graphics.DrawString( _
           "Inner Container", _
           font, _
           brush, _
           New PointF(20, 10))
        graphics.EndContainer(innerContainer)

        graphics.DrawString("Outer Container", font, brush, New PointF(20, 50))

        graphics.EndContainer(outerContainer)

        graphics.DrawString("Graphics Object", font, brush, New PointF(20, 90))

Graphics graphics = e.Graphics;
GraphicsContainer innerContainer;
GraphicsContainer outerContainer;
SolidBrush brush = new SolidBrush(Color.Blue);
FontFamily fontFamily = new FontFamily("Times New Roman");
Font font = new Font(fontFamily, 36, FontStyle.Regular, GraphicsUnit.Pixel);

graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

outerContainer = graphics.BeginContainer();

graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;

innerContainer = graphics.BeginContainer();
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
graphics.DrawString(
   "Inner Container",
   font,
   brush,
   new PointF(20, 10));
graphics.EndContainer(innerContainer);

graphics.DrawString(
   "Outer Container",
   font,
   brush,
   new PointF(20, 50));

graphics.EndContainer(outerContainer);

graphics.DrawString(
   "Graphics Object",
   font,
   brush,
   new PointF(20, 90));

In der folgenden Abbildung sind die drei Zeichenfolgen dargestellt. Die aus dem inneren Container und dem Graphics-Objekt gezeichneten Zeichenfolgen werden durch Antialiasing geglättet. Die Zeichenfolge aus dem äußeren Container wird nicht durch Antialiasing geglättet, da die TextRenderingHint-Eigenschaft den Wert SingleBitPerPixel hat.

Geschachtelte Container

Siehe auch

Referenz

Graphics

Konzepte

Verwalten des Zustands eines Graphics-Objekts