共用方式為


使用巢狀圖形容器

GDI+ 提供容器,可讓您用來暫時取代或增強 Graphics 物件中狀態的一部分。 您可以呼叫 Graphics 物件的 BeginContainer 方法來建立容器。 您可以重複呼叫 BeginContainer,以形成巢狀容器。 每次對 BeginContainer 的呼叫必須與對 EndContainer 的呼叫配對。

巢狀容器中的轉換

下列範例會在該 Graphics 物件內建立 Graphics 物件和容器。 Graphics 物件的世界轉換是 x 方向的 100 個單位,Y 方向為 80 個單位。 容器的世界轉換是 30 度旋轉。 程序碼會呼叫 DrawRectangle(pen, -60, -30, 120, 60) 兩次。 第一次呼叫 DrawRectangle 是在容器內;也就是說,呼叫位於呼叫 BeginContainerEndContainer之間。 第二次呼叫 DrawRectangle 是在呼叫 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)

在上述程式碼中,從容器內繪製的矩形會先由容器的世界轉換 (旋轉) 轉換,然後由 Graphics 物件的世界轉換 (平移) 來轉換。 從容器外部繪製的矩形只會由 Graphics 物件 (平移) 的世界轉換來轉換。 下圖顯示兩個矩形:

顯示巢狀容器的圖例。

巢狀容器中的裁剪

下列範例示範巢狀容器如何處理裁剪區域。 程式碼會在該 Graphics 物件內建立 Graphics 物件和容器。 Graphics 物件的裁剪區域是矩形,而容器的裁剪區域則是省略符號。 程序碼會呼叫 DrawLine 方法兩次。 第一次呼叫 DrawLine 是在容器內,而對 DrawLine 的第二次呼叫是在容器外部 (在呼叫 EndContainer 之後)。 第一線條是由兩個裁剪區域的交集所裁剪。 第二線條只會由 Graphics 物件的矩形裁剪區域裁剪。

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)

下圖顯示兩條裁剪的線條:

圖例顯示具有裁剪線條的巢狀容器。

如上述兩個範例所示,轉換和裁剪區域會累積在巢狀容器中。 如果您設定容器和 Graphics 物件的世界轉換,這兩個轉換都會套用至從容器內繪製的專案。 容器的轉換會先套用,並套用 Graphics 物件的轉換。 如果您設定容器的裁剪區域和 Graphics 物件,則從容器內繪製的項目將會由兩個裁剪區域的交集裁剪。

巢狀容器中的品質設定

巢狀容器中的品質設定 (SmoothingModeTextRenderingHint等) 不是累計的:相反地,容器的品質設定會暫時取代 Graphics 物件的品質設定。 當您建立新的容器時,該容器的品質設定會設定為預設值。 例如,假設您有一個具有平滑模式 AntiAliasGraphics 物件。 當您建立容器時,容器內的平滑模式是預設的平滑模式。 您可以自由設定容器的平滑模式,而從容器內繪製的任何項目都會依據您設定的模式繪製。 在呼叫 EndContainer 之後繪製的項目會依據呼叫 BeginContainer 之前已就緒的平滑模式 (AntiAlias) 繪製。

數層巢狀容器

您不限於 Graphics 物件中的一個容器。 您可以建立一連串的容器,每個容器都巢狀於前一個容器中,而且您可以指定每個巢狀容器的世界轉換、裁剪區域及品質設定。 如果您從最內層容器內呼叫繪圖方法,則會依序套用轉換,從最內層容器開始,並以最外層容器結尾。 從最內層容器內繪製的項目將會由所有裁剪區域的交集裁剪。

下列範例會建立 Graphics 物件,並將其文字轉譯提示設定為 AntiAlias。 程序碼會建立兩個容器,一個巢狀於另一個容器內。 外部容器的文字轉譯提示會設定為 SingleBitPerPixel,而內部容器的文字轉譯提示會設定為 AntiAlias。 程序碼會繪製三個字串:一個來自內部容器、一個來自外部容器,另一個來自 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))

下圖顯示三個字串。 從內部容器和 Graphics 物件繪製的字串會透過消除鋸齒來平滑。 從外部容器繪製的字串不會透過消除鋸齒處理來平滑,因為 TextRenderingHint 屬性設定為 SingleBitPerPixel

顯示從巢狀容器繪製之字串的圖例。

另請參閱