Použití vnořených grafických kontejnerů
GDI+ poskytuje kontejnery, které můžete použít k dočasnému nahrazení nebo rozšíření části stavu v objektu Graphics. Kontejner vytvoříte voláním BeginContainer metody objektu Graphics. Můžete volat BeginContainer opakovaně k vytvoření vnořených kontejnerů. Každé volání BeginContainer musí být spárováno s voláním EndContainer.
Transformace v vnořených kontejnerech
Následující příklad vytvoří objekt Graphics a kontejner v rámci tohoto Graphics objektu. Transformace objektu Graphics je posunutí o 100 jednotek v ose x a o 80 jednotek v ose y. Světová transformace kontejneru je 30stupňová rotace. Kód provede volání DrawRectangle(pen, -60, -30, 120, 60)
dvakrát. První volání DrawRectangle je uvnitř kontejneru; to znamená, že volání je mezi voláními BeginContainer a EndContainer. Druhé volání DrawRectangle je po volání 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)
V předchozím kódu se obdélník nakreslený uvnitř kontejneru transformuje jako první světovou transformací kontejneru (otočení) a pak světovou transformací objektu Graphics (překlad). Obdélník nakreslený z vnějšího kontejneru je transformován pouze světovou transformací objektu Graphics (překlad). Následující obrázek znázorňuje dva obdélníky:
Výřez v vnořených kontejnerech
Následující příklad ukazuje, jak vnořené kontejnery zpracovávají oblasti výřezu. Kód vytvoří objekt Graphics a kontejner v rámci Graphics objektu. Oblast výřezu Graphics objektu je obdélník a oblast výřezu kontejneru je elipsa. Kód provádí dvě volání metody DrawLine. První volání DrawLine je uvnitř kontejneru a druhé volání DrawLine je mimo kontejner (po volání EndContainer). První řádek je omezován křížením dvou oblastí výřezu. Druhý řádek je oříznut pouze obdélníkovým výřezem Graphics objektu.
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)
Následující obrázek znázorňuje dvě oříznuté čáry:
Jak ukazují dva předchozí příklady, transformace a oblasti výřezu jsou kumulativní v vnořených kontejnerech. Pokud nastavíte světové transformace kontejneru a objektu Graphics, použijí se obě transformace u položek vytažených z kontejneru. Nejprve se použije transformace kontejneru a použije se druhá transformace objektu Graphics. Pokud nastavíte ořezové oblasti kontejneru a objektu Graphics, položky vykreslené uvnitř kontejneru budou ořezány průnikem obou ořezových oblastí.
Nastavení kvality v vnořených kontejnerech
Nastavení kvality (SmoothingMode, TextRenderingHinta podobně) v vnořených kontejnerech nejsou kumulativní; nastavení kvality kontejneru dočasně nahradí nastavení kvality objektu Graphics. Při vytváření nového kontejneru se nastavení kvality pro tento kontejner nastaví na výchozí hodnoty. Předpokládejme například, že máte objekt Graphics s režimem vyhlazování AntiAlias. Při vytváření kontejneru je režim vyhlazování uvnitř kontejneru výchozím režimem vyhlazování. Můžete nastavit režim vyhlazování kontejneru a všechny položky nakreslené z kontejneru budou nakresleny podle vámi nastaveného režimu. Položky vykreslené po volání EndContainer budou vykresleny podle režimu vyhlazování (AntiAlias), který byl zaveden před voláním BeginContainer.
Několik vrstev vnořených kontejnerů
Nejste omezeni na jeden kontejner v objektu Graphics. Můžete vytvořit posloupnost kontejnerů, z nichž každý je vnořený do předchozího, a můžete určit světovou transformaci, ořez oblasti a nastavení kvality každého z těchto vnořených kontejnerů. Pokud zavoláte metodu kreslení z vnitřního kontejneru, transformace se použijí v pořadí, od nejvnitřnějšího kontejneru až po nejvnější kontejner. Položky nakreslené z vnitřního kontejneru se vystřihnou průnikem všech oblastí výřezu.
Následující příklad vytvoří objekt Graphics a nastaví jeho nápovědu pro vykreslování textu na AntiAlias. Kód vytvoří dva kontejnery, jeden vnořený uvnitř druhého. Nápověda pro vykreslování textu vnějšího kontejneru je nastavena na SingleBitPerPixela nápověda pro vykreslování textu vnitřního kontejneru je nastavena na AntiAlias. Kód nakreslí tři řetězce: jeden z vnitřního kontejneru, jeden z vnějšího kontejneru a druhý z samotného objektu Graphics.
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))
Následující obrázek znázorňuje tři řetězce. Řetězce nakreslené z vnitřního kontejneru a z objektu Graphics jsou vyhlazovány antialiasingem. Řetězec nakreslený z vnějšího kontejneru není vyhlazován antialiasingem, protože TextRenderingHint vlastnost je nastavena na SingleBitPerPixel.
Viz také
.NET Desktop feedback