Delen via


Geneste grafische containers gebruiken

GDI+ biedt containers waarmee u tijdelijk een deel van de status in een Graphics-object kunt vervangen of uitbreiden. U maakt een container door de BeginContainer methode van een Graphics-object aan te roepen. U kunt BeginContainer herhaaldelijk gebruiken om geneste containers te vormen. Elke aanroep naar BeginContainer moet worden gekoppeld aan een aanroep naar EndContainer.

Transformaties in geneste containers

In het volgende voorbeeld wordt een Graphics-object en een container binnen dat Graphics object gemaakt. De wereldtransformatie van het Graphics object is een vertaling van 100 eenheden in de x-richting en 80 eenheden in de y-richting. De wereldtransformatie van de container is een draaiing van 30 graden. De code roept twee keer DrawRectangle(pen, -60, -30, 120, 60) aan. De eerste aanroep van DrawRectangle bevindt zich in de container; dat wil zeggen dat de aanroep is tussen de aanroepen van BeginContainer en EndContainer. De tweede aanroep van DrawRectangle is na de aanroep van EndContainer.

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);
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)

In de voorgaande code wordt de rechthoek die vanuit de container is getekend, eerst getransformeerd door de wereldtransformatie van de container (rotatie) en vervolgens door de wereldtransformatie van het Graphics-object (vertaling). De rechthoek die van buiten de container is getekend, wordt alleen getransformeerd door de wereldtransformatie van het Graphics-object (vertaling). In de volgende afbeelding ziet u de twee rechthoeken:

Afbeelding waarin geneste containers worden weergegeven.

Knippen in geneste containers

In het volgende voorbeeld ziet u hoe geneste containers clipping-regio's verwerken. De code maakt een Graphics-object en een container binnen dat Graphics object. Het knipgebied van het Graphics-object is een rechthoek en het knipgebied van de container is een ellips. De code roept twee aanroepen uit naar de methode DrawLine. De eerste aanroep naar DrawLine bevindt zich in de container en de tweede aanroep van DrawLine bevindt zich buiten de container (na de aanroep naar EndContainer). De eerste regel wordt afgekapt door het snijpunt van de twee knipregio's. De tweede regel wordt alleen afgesneden door het rechthoekige knipgebied van het Graphics-object.

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);
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)

In de volgende afbeelding ziet u de twee geknipte regels:

Illustratie die een geneste container met afgeknipte lijnen toont.

Zoals in de twee voorgaande voorbeelden wordt weergegeven, zijn transformaties en knipregio's cumulatief in geneste containers. Als u de wereldtransformaties van de container en het Graphics-object instelt, worden beide transformaties toegepast op items die vanuit de container zijn getekend. De transformatie van de container wordt eerst toegepast en de transformatie van het Graphics-object wordt tweede toegepast. Als u de knipregio's van de container en het Graphics object instelt, worden items die vanuit de container zijn getekend, geknipt door het snijpunt van de twee knipregio's.

Kwaliteitsinstellingen in genestelde container

Kwaliteitsinstellingen (SmoothingMode, TextRenderingHinten dergelijke) in geneste containers zijn niet cumulatief; In plaats daarvan vervangen de kwaliteitsinstellingen van de container tijdelijk de kwaliteitsinstellingen van een Graphics-object. Wanneer u een nieuwe container maakt, worden de kwaliteitsinstellingen voor die container ingesteld op standaardwaarden. Stel dat u een Graphics object hebt met een vloeiende modus van AntiAlias. Wanneer u een container maakt, is de antialiasingmodus in de container de standaardmodus voor antialiasing. U kunt de gladstrijkmodus van de container instellen en alle items die vanuit de container worden getekend, worden getekend volgens de modus die u instelt. Items worden na het aanroepen van EndContainer getekend volgens de vereffeningsmodus (AntiAlias) die aanwezig was voor de aanroep naar BeginContainer.

Verschillende lagen van geneste containers

U bent niet beperkt tot één container in een Graphics-object. U kunt een reeks containers maken, elk genest in het voorgaande, en u kunt de wereldtransformatie, het knipgebied en de kwaliteitsinstellingen van elk van deze geneste containers opgeven. Als u een tekenmethode aanroept vanuit de binnenste container, worden de transformaties op volgorde toegepast, beginnend met de binnenste container en eindigend met de buitenste container. Items die uit de binnenste container worden getrokken, worden afgekapt door het snijpunt van alle knipregio's.

In het volgende voorbeeld wordt een Graphics object gemaakt en wordt de hint voor tekstweergave ingesteld op AntiAlias. De code maakt twee containers, één geneste binnen de andere. De hint voor tekstweergave van de buitenste container is ingesteld op SingleBitPerPixelen de hint voor tekstweergave van de binnenste container is ingesteld op AntiAlias. De code tekent drie tekenreeksen: één uit de binnenste container, één uit de buitenste container en één uit het Graphics-object zelf.

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));
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))

In de volgende afbeelding ziet u de drie tekenreeksen. De lijnen afkomstig uit de binnenste container en van het Graphics-object worden verzacht door anti-aliasing. De string die uit de buitenste container is gehaald, wordt niet afgevlakt door antialiasing omdat de eigenschap TextRenderingHint is ingesteld op SingleBitPerPixel.

afbeelding waarin de tekenreeksen worden weergegeven die zijn getekend uit geneste containers.

Zie ook