《C# GDI+ 破境之道》:第一境 GDI+基础 —— 第二节:画矩形

有了上一节画线的基础,画矩形的各种边线就特别好理解了,所以,本节在矩形边线上,就不做过多的讲解了,关注一下画“随机矩形”的具体实现就好。与画线相比较,画矩形稍微复杂的一点就是在于它多了很多填充的样式。接下来,我们就来细细品味一番。

同样,一个窗体项目,窗体的布局风格与上一节的保持一致:

 1 namespace MikeWare.GdiPlus.Rectangles
 2 {
 3     using System;
 4     using System.Collections.Generic;
 5     using System.Drawing;
 6     using System.Drawing.Drawing2D;
 7     using System.Windows.Forms;
 8 
 9     public partial class FormDrawRectangles : Form
10     {
11         private Random random = null;
12         private Color penColor = Color.Transparent;
13 
14         public FormDrawRectangles()
15         {
16             InitializeComponent();
17             random = new Random(DateTime.Now.Millisecond);
18             penColor = GetRandomColor();
19         }
20 
21         private Point GetRandomPoint()
22         {
23             return new Point(random.Next(0, ClientRectangle.Width), random.Next(0, ClientRectangle.Height - pnlToolbox.Height));
24         }
25 
26         private Rectangle GetRandomRectangle()
27         {
28             var pointA = GetRandomPoint();
29             var pointB = GetRandomPoint();
30 
31             return new Rectangle(Math.Min(pointA.X, pointB.X)
32                 , Math.Min(pointA.Y, pointB.Y)
33                 , Math.Abs(pointA.X - pointB.X)
34                 , Math.Abs(pointA.Y - pointB.Y));
35         }
36 
37         private Color GetRandomColor()
38         {
39             return Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
40         }
41 
42         private void ShowInformation(string message)
43         {
44             lblInformation.Text = message;
45         }
46 
47         private void btnChangePenColor_Click(object sender, EventArgs e)
48         {
49             if (colors.ShowDialog(this) == DialogResult.OK)
50             {
51                 penColor = colors.Color;
52             }
53         }
54 
55         private void btnSwitchDoubleBuffered_Click(object sender, EventArgs e)
56         {
57             DoubleBuffered = !DoubleBuffered;
58 
59             ShowInformation($"二级缓冲:{DoubleBuffered}。");
60         }
61 
62         private void btnDrawRandomRectangle_Click(object sender, EventArgs e)
63         {
64             var rectangle = GetRandomRectangle();
65 
66             var style = (DashStyle)(random.Next(0, 6));
67             var dashCaps = new List<int> { 0, 2, 3 };
68             var dashCap = (DashCap)dashCaps[random.Next(0, 3)];
69 
70             using (var g = CreateGraphics())
71             using (var pen = new Pen(penColor, 4f))
72             using (var brush = new LinearGradientBrush(rectangle, Color.Red, Color.Blue, LinearGradientMode.ForwardDiagonal))
73             {
74                 g.Clear(SystemColors.AppWorkspace);
75                 g.SmoothingMode = SmoothingMode.HighQuality;
76                 pen.DashStyle = style;
77                 pen.DashCap = dashCap;
78                 g.DrawRectangle(pen, rectangle);
79             }
80 
81             ShowInformation($"随机矩形,{rectangle},虚线冒:{dashCap.ToString()},线条样式:{style.ToString()}。");
82         }
83 
84         ……    
85     }
86 }
命名空间引用、私有变量、构造函数及辅助方法

与上一节给出的窗体定义及辅助方法雷同,这里不做过多说明,增加了两个辅助方法,一个是获取随机矩形Rectangle GetRandomRectangle(),一个是获取随机颜色Color GetRandomColor(),相信什么是矩形和颜色,生物老师都教过:)而且本节的重点也不在边线的绘制上,其基本方法就是Graphics.DrawRectangle(Pen pen, Rectangle rect),也直接给出了绘制“随机矩形”的代码,有了画线的基础,应该没什么问题了。

下面,重点来了:

1、绘制具有渐变色填充的矩形

 1 private void btnFillLinearGradientColor_Click(object sender, EventArgs e)
 2 {
 3     var rectangle1 = GetRandomRectangle();
 4     var rectangle2 = GetRandomRectangle();
 5 
 6     var gradient = (LinearGradientMode)(random.Next(0, 4));
 7     var angle = (random.Next(0, 361));
 8 
 9     using (var g = CreateGraphics())
10     {
11         g.Clear(SystemColors.AppWorkspace);
12         g.SmoothingMode = SmoothingMode.HighQuality;
13         using (var brush = new LinearGradientBrush(rectangle1, GetRandomColor(), GetRandomColor(), gradient))
14         {
15             g.FillRectangle(brush, rectangle1);
16         }
17 
18         using (var brush = new LinearGradientBrush(rectangle2, GetRandomColor(), GetRandomColor(), angle, 0 == angle % 2))
19         {
20             g.FillRectangle(brush, rectangle2);
21         }
22     }
23 
24     ShowInformation($"渐变色填充,{rectangle1},LinearGradient:{gradient};{rectangle2},Angle:{angle}。");
25 }
渐变色填充 —— btnFillLinearGradientColor_Click

绘制渐变色填充,关键在于构造一个合适的LinearGradientBrush,然后调用Graphics.FillRectangle(Brush brush, Rectangle rect)就可以了。

        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.LinearGradientBrush
        //     class with the specified points and colors.
        //
        // Parameters:
        //   point1:
        //     A System.Drawing.PointF structure that represents the starting point of the linear
        //     gradient.
        //
        //   point2:
        //     A System.Drawing.PointF structure that represents the endpoint of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color of the linear
        //     gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color of the linear
        //     gradient.
        public LinearGradientBrush(PointF point1, PointF point2, Color color1, Color color2);
//
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.LinearGradientBrush
        //     class with the specified points and colors.
        //
        // Parameters:
        //   point1:
        //     A System.Drawing.Point structure that represents the starting point of the linear
        //     gradient.
        //
        //   point2:
        //     A System.Drawing.Point structure that represents the endpoint of the linear gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color of the linear
        //     gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color of the linear
        //     gradient.
        public LinearGradientBrush(Point point1, Point point2, Color color1, Color color2);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush based
        //     on a rectangle, starting and ending colors, and an orientation mode.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.RectangleF structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   linearGradientMode:
        //     A System.Drawing.Drawing2D.LinearGradientMode enumeration element that specifies
        //     the orientation of the gradient. The orientation determines the starting and
        //     ending points of the gradient. For example, LinearGradientMode.ForwardDiagonal
        //     specifies that the starting point is the upper-left corner of the rectangle and
        //     the ending point is the lower-right corner of the rectangle.
        public LinearGradientBrush(RectangleF rect, Color color1, Color color2, LinearGradientMode linearGradientMode);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush class
        //     based on a rectangle, starting and ending colors, and orientation.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.Rectangle structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   linearGradientMode:
        //     A System.Drawing.Drawing2D.LinearGradientMode enumeration element that specifies
        //     the orientation of the gradient. The orientation determines the starting and
        //     ending points of the gradient. For example, LinearGradientMode.ForwardDiagonal
        //     specifies that the starting point is the upper-left corner of the rectangle and
        //     the ending point is the lower-right corner of the rectangle.
        public LinearGradientBrush(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush class
        //     based on a rectangle, starting and ending colors, and an orientation angle.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.RectangleF structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   angle:
        //     The angle, measured in degrees clockwise from the x-axis, of the gradient's orientation
        //     line.
        public LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush class
        //     based on a rectangle, starting and ending colors, and an orientation angle.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.Rectangle structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   angle:
        //     The angle, measured in degrees clockwise from the x-axis, of the gradient's orientation
        //     line.
        public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush class
        //     based on a rectangle, starting and ending colors, and an orientation angle.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.RectangleF structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   angle:
        //     The angle, measured in degrees clockwise from the x-axis, of the gradient's orientation
        //     line.
        //
        //   isAngleScaleable:
        //     Set to true to specify that the angle is affected by the transform associated
        //     with this System.Drawing.Drawing2D.LinearGradientBrush; otherwise, false.
        public LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle, bool isAngleScaleable);
//
        // Summary:
        //     Creates a new instance of the System.Drawing.Drawing2D.LinearGradientBrush class
        //     based on a rectangle, starting and ending colors, and an orientation angle.
        //
        // Parameters:
        //   rect:
        //     A System.Drawing.Rectangle structure that specifies the bounds of the linear
        //     gradient.
        //
        //   color1:
        //     A System.Drawing.Color structure that represents the starting color for the gradient.
        //
        //   color2:
        //     A System.Drawing.Color structure that represents the ending color for the gradient.
        //
        //   angle:
        //     The angle, measured in degrees clockwise from the x-axis, of the gradient's orientation
        //     line.
        //
        //   isAngleScaleable:
        //     Set to true to specify that the angle is affected by the transform associated
        //     with this System.Drawing.Drawing2D.LinearGradientBrush; otherwise, false.
        public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle, bool isAngleScaleable);
System.Drawing.Drawing2D.LinearGradientBrush

从LinearGradientBrush的一系列构造函数可以看出,LinearGradientBrush意在指出完成从一种颜色渐变到另一种颜色的渐变周期。

这里我们着重说一下LinearGradientBrush的第一个参数,无论是一个Rectangle还是两个Point,他们描述的是渐变色完成的区间。为了理解和描述上的方便,我们假设绘制的是一个水平方向的渐变,

这个时候,渐变区间与我们要填充的矩形并没有交集,我们可以这样理解,这个渐变区间会以定义的区域为原点,向四周扩散,

然后在填充的时候,只保留了我们要填充的矩形区域可见,

OK,假设我已经把这个关系说清楚了:)在有就是LinearGradientMode这个枚举,

    //
    // Summary:
    //     Specifies the direction of a linear gradient.
    public enum LinearGradientMode
    {
        //
        // Summary:
        //     Specifies a gradient from left to right.
        Horizontal = 0,
        //
        // Summary:
        //     Specifies a gradient from top to bottom.
        Vertical = 1,
        //
        // Summary:
        //     Specifies a gradient from upper left to lower right.
        ForwardDiagonal = 2,
        //
        // Summary:
        //     Specifies a gradient from upper right to lower left.
        BackwardDiagonal = 3
    }
System.Drawing.Drawing2D.LinearGradientMode

它列举了从第一种颜色过渡到第二种颜色的方向,从左到右,从上到下,从左上到右下,从右上到左下四个比较正规的方向;

关于LinearGradientBrush的另一个参数(float angle),它用来指示颜色过渡的方向,结合LinearGradientMode理解,同时,指出,angle可以为负数,下图帮助理解一下GDI+中的angle:

LinearGradientBrush类还有一些非常有用的属性和方法,可以帮助完成一些更为复杂的任务,这里就不细说了,又需要的童鞋可以深入研究一下:)

        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.ColorBlend that defines a multicolor
        //     linear gradient.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.ColorBlend that defines a multicolor linear gradient.
        public ColorBlend InterpolationColors { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.Blend that specifies positions and factors
        //     that define a custom falloff for the gradient.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.Blend that represents a custom falloff for the gradient.
        public Blend Blend { get; set; }
        //
        // Summary:
        //     Gets or sets a value indicating whether gamma correction is enabled for this
        //     System.Drawing.Drawing2D.LinearGradientBrush.
        //
        // Returns:
        //     The value is true if gamma correction is enabled for this System.Drawing.Drawing2D.LinearGradientBrush;
        //     otherwise, false.
        public bool GammaCorrection { get; set; }
        //
        // Summary:
        //     Gets a rectangular region that defines the starting and ending points of the
        //     gradient.
        //
        // Returns:
        //     A System.Drawing.RectangleF structure that specifies the starting and ending
        //     points of the gradient.
        public RectangleF Rectangle { get; }
        //
        // Summary:
        //     Gets or sets the starting and ending colors of the gradient.
        //
        // Returns:
        //     An array of two System.Drawing.Color structures that represents the starting
        //     and ending colors of the gradient.
        public Color[] LinearColors { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.WrapMode enumeration that indicates the
        //     wrap mode for this System.Drawing.Drawing2D.LinearGradientBrush.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.WrapMode that specifies how fills drawn with this
        //     System.Drawing.Drawing2D.LinearGradientBrush are tiled.
        public WrapMode WrapMode { get; set; }
        //
        // Summary:
        //     Gets or sets a copy System.Drawing.Drawing2D.Matrix that defines a local geometric
        //     transform for this System.Drawing.Drawing2D.LinearGradientBrush.
        //
        // Returns:
        //     A copy of the System.Drawing.Drawing2D.Matrix that defines a geometric transform
        //     that applies only to fills drawn with this System.Drawing.Drawing2D.LinearGradientBrush.
        public Matrix Transform { get; set; }

        //
        // Summary:
        //     Creates an exact copy of this System.Drawing.Drawing2D.LinearGradientBrush.
        //
        // Returns:
        //     The System.Drawing.Drawing2D.LinearGradientBrush this method creates, cast as
        //     an object.
        public override object Clone();
        //
        // Summary:
        //     Multiplies the System.Drawing.Drawing2D.Matrix that represents the local geometric
        //     transform of this System.Drawing.Drawing2D.LinearGradientBrush by the specified
        //     System.Drawing.Drawing2D.Matrix in the specified order.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix by which to multiply the geometric transform.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies in which order to multiply
        //     the two matrices.
        public void MultiplyTransform(Matrix matrix, MatrixOrder order);
        //
        // Summary:
        //     Multiplies the System.Drawing.Drawing2D.Matrix that represents the local geometric
        //     transform of this System.Drawing.Drawing2D.LinearGradientBrush by the specified
        //     System.Drawing.Drawing2D.Matrix by prepending the specified System.Drawing.Drawing2D.Matrix.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix by which to multiply the geometric transform.
        public void MultiplyTransform(Matrix matrix);
        //
        // Summary:
        //     Resets the System.Drawing.Drawing2D.LinearGradientBrush.Transform property to
        //     identity.
        public void ResetTransform();
        //
        // Summary:
        //     Rotates the local geometric transform by the specified amount. This method prepends
        //     the rotation to the transform.
        //
        // Parameters:
        //   angle:
        //     The angle of rotation.
        public void RotateTransform(float angle);
        //
        // Summary:
        //     Rotates the local geometric transform by the specified amount in the specified
        //     order.
        //
        // Parameters:
        //   angle:
        //     The angle of rotation.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies whether to append or prepend
        //     the rotation matrix.
        public void RotateTransform(float angle, MatrixOrder order);
        //
        // Summary:
        //     Scales the local geometric transform by the specified amounts. This method prepends
        //     the scaling matrix to the transform.
        //
        // Parameters:
        //   sx:
        //     The amount by which to scale the transform in the x-axis direction.
        //
        //   sy:
        //     The amount by which to scale the transform in the y-axis direction.
        public void ScaleTransform(float sx, float sy);
        //
        // Summary:
        //     Scales the local geometric transform by the specified amounts in the specified
        //     order.
        //
        // Parameters:
        //   sx:
        //     The amount by which to scale the transform in the x-axis direction.
        //
        //   sy:
        //     The amount by which to scale the transform in the y-axis direction.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies whether to append or prepend
        //     the scaling matrix.
        public void ScaleTransform(float sx, float sy, MatrixOrder order);
        //
        // Summary:
        //     Creates a linear gradient with a center color and a linear falloff to a single
        //     color on both ends.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies the center of the gradient (the point
        //     where the gradient is composed of only the ending color).
        //
        //   scale:
        //     A value from 0 through1 that specifies how fast the colors falloff from the starting
        //     color to focus (ending color)
        public void SetBlendTriangularShape(float focus, float scale);
        //
        // Summary:
        //     Creates a linear gradient with a center color and a linear falloff to a single
        //     color on both ends.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies the center of the gradient (the point
        //     where the gradient is composed of only the ending color).
        public void SetBlendTriangularShape(float focus);
        //
        // Summary:
        //     Creates a gradient falloff based on a bell-shaped curve.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies the center of the gradient (the point
        //     where the gradient is composed of only the ending color).
        //
        //   scale:
        //     A value from 0 through 1 that specifies how fast the colors falloff from the
        //     focus.
        public void SetSigmaBellShape(float focus, float scale);
        //
        // Summary:
        //     Creates a gradient falloff based on a bell-shaped curve.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies the center of the gradient (the point
        //     where the starting color and ending color are blended equally).
        public void SetSigmaBellShape(float focus);
        //
        // Summary:
        //     Translates the local geometric transform by the specified dimensions. This method
        //     prepends the translation to the transform.
        //
        // Parameters:
        //   dx:
        //     The value of the translation in x.
        //
        //   dy:
        //     The value of the translation in y.
        public void TranslateTransform(float dx, float dy);
        //
        // Summary:
        //     Translates the local geometric transform by the specified dimensions in the specified
        //     order.
        //
        // Parameters:
        //   dx:
        //     The value of the translation in x.
        //
        //   dy:
        //     The value of the translation in y.
        //
        //   order:
        //     The order (prepend or append) in which to apply the translation.
        public void TranslateTransform(float dx, float dy, MatrixOrder order);
System.Drawing.Drawing2D.LinearGradientBrush的属性和方法

2、绘制系统画刷填充矩形

 1 private void btnFillWithSystemBrushes_Click(object sender, EventArgs e)
 2 {
 3     var rectangle = GetRandomRectangle();
 4 
 5     var systemBrushes = new List<Brush> {
 6     SystemBrushes.GradientInactiveCaption ,
 7     SystemBrushes.Window                  ,
 8     SystemBrushes.ScrollBar               ,
 9     SystemBrushes.MenuText                ,
10     SystemBrushes.MenuHighlight           ,
11     SystemBrushes.MenuBar                 ,
12     SystemBrushes.Menu                    ,
13     SystemBrushes.InfoText                ,
14     SystemBrushes.Info                    ,
15     SystemBrushes.InactiveCaptionText     ,
16     SystemBrushes.InactiveBorder          ,
17     SystemBrushes.InactiveCaption         ,
18     SystemBrushes.HotTrack                ,
19     SystemBrushes.HighlightText           ,
20     SystemBrushes.Highlight               ,
21     SystemBrushes.GrayText                ,
22     SystemBrushes.WindowText              ,
23     SystemBrushes.GradientActiveCaption   ,
24     SystemBrushes.ActiveBorder            ,
25     SystemBrushes.ActiveCaption           ,
26     SystemBrushes.ActiveCaptionText       ,
27     SystemBrushes.AppWorkspace            ,
28     SystemBrushes.ButtonFace              ,
29     SystemBrushes.ButtonHighlight         ,
30     SystemBrushes.WindowFrame             ,
31     SystemBrushes.ButtonShadow            ,
32     SystemBrushes.ControlLightLight       ,
33     SystemBrushes.ControlLight            ,
34     SystemBrushes.ControlDark             ,
35     SystemBrushes.ControlDarkDark         ,
36     SystemBrushes.ControlText             ,
37     SystemBrushes.Desktop                 ,
38     SystemBrushes.Control                 ,};
39 
40     var brush = systemBrushes[random.Next(0, systemBrushes.Count)];
41 
42     using (var g = CreateGraphics())
43     {
44         g.Clear(SystemColors.AppWorkspace);
45         g.SmoothingMode = SmoothingMode.HighQuality;
46         g.FillRectangle(brush, rectangle);
47     }
48 
49     ShowInformation($"画刷填充,{rectangle},画刷名称:{(brush as SolidBrush)?.Color.Name}。");
50 }
画刷填充 —— btnFillWithSystemBrushes_Click

本示例取用系统画刷SystemBrushes来作为填充,其实就是Windows系统的一些画刷配置,比如桌面背景色、按钮颜色等。除非制作自定义控件或组件,否则,其它场景可能很少应用。不过,这个示例也同样适用于SolidBrush,就是纯色画刷。没什么特表之处,一笔带过吧。

3、绘制镶嵌填充矩形

 1 private void btnFillWithHatchBrush_Click(object sender, EventArgs e)
 2 {
 3     var rectangle = GetRandomRectangle();
 4 
 5     var style = (HatchStyle)(random.Next(0, 53));
 6     var foreColor = GetRandomColor();
 7     var backColor = GetRandomColor();
 8 
 9     using (var g = CreateGraphics())
10     using (var brush = new HatchBrush(style, foreColor, backColor))
11     {
12         g.Clear(SystemColors.AppWorkspace);
13         g.SmoothingMode = SmoothingMode.HighQuality;
14         g.FillRectangle(brush, rectangle);
15     }
16 
17     ShowInformation($"镶嵌填充,{rectangle},前景色:{foreColor},背景色:{backColor},填充样式:{style.ToString()}。");
18 }
镶嵌填充 —— btnFillWithHatchBrush_Click

System.Drawing.Drawing2D.HatchBrush是一个比较有意思的画刷,它根据两种颜色和不同的镶嵌样式,组合出各种不同的图案,比较适合作为场景的背景,建议多玩儿玩儿。

技术上没什么特别点,主要是支持的样式比较多,就不一一介绍了。

namespace System.Drawing.Drawing2D
{
    //
    // Summary:
    //     Specifies the different patterns available for System.Drawing.Drawing2D.HatchBrush
    //     objects.
    public enum HatchStyle
    {
        //
        // Summary:
        //     A pattern of horizontal lines.
        Horizontal = 0,
        //
        // Summary:
        //     Specifies hatch style System.Drawing.Drawing2D.HatchStyle.Horizontal.
        Min = 0,
        //
        // Summary:
        //     A pattern of vertical lines.
        Vertical = 1,
        //
        // Summary:
        //     A pattern of lines on a diagonal from upper left to lower right.
        ForwardDiagonal = 2,
        //
        // Summary:
        //     A pattern of lines on a diagonal from upper right to lower left.
        BackwardDiagonal = 3,
        //
        // Summary:
        //     Specifies horizontal and vertical lines that cross.
        Cross = 4,
        //
        // Summary:
        //     Specifies the hatch style System.Drawing.Drawing2D.HatchStyle.Cross.
        LargeGrid = 4,
        //
        // Summary:
        //     Specifies hatch style System.Drawing.Drawing2D.HatchStyle.SolidDiamond.
        Max = 4,
        //
        // Summary:
        //     A pattern of crisscross diagonal lines.
        DiagonalCross = 5,
        //
        // Summary:
        //     Specifies a 5-percent hatch. The ratio of foreground color to background color
        //     is 5:95.
        Percent05 = 6,
        //
        // Summary:
        //     Specifies a 10-percent hatch. The ratio of foreground color to background color
        //     is 10:90.
        Percent10 = 7,
        //
        // Summary:
        //     Specifies a 20-percent hatch. The ratio of foreground color to background color
        //     is 20:80.
        Percent20 = 8,
        //
        // Summary:
        //     Specifies a 25-percent hatch. The ratio of foreground color to background color
        //     is 25:75.
        Percent25 = 9,
        //
        // Summary:
        //     Specifies a 30-percent hatch. The ratio of foreground color to background color
        //     is 30:70.
        Percent30 = 10,
        //
        // Summary:
        //     Specifies a 40-percent hatch. The ratio of foreground color to background color
        //     is 40:60.
        Percent40 = 11,
        //
        // Summary:
        //     Specifies a 50-percent hatch. The ratio of foreground color to background color
        //     is 50:50.
        Percent50 = 12,
        //
        // Summary:
        //     Specifies a 60-percent hatch. The ratio of foreground color to background color
        //     is 60:40.
        Percent60 = 13,
        //
        // Summary:
        //     Specifies a 70-percent hatch. The ratio of foreground color to background color
        //     is 70:30.
        Percent70 = 14,
        //
        // Summary:
        //     Specifies a 75-percent hatch. The ratio of foreground color to background color
        //     is 75:25.
        Percent75 = 15,
        //
        // Summary:
        //     Specifies a 80-percent hatch. The ratio of foreground color to background color
        //     is 80:100.
        Percent80 = 16,
        //
        // Summary:
        //     Specifies a 90-percent hatch. The ratio of foreground color to background color
        //     is 90:10.
        Percent90 = 17,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the right from top points to bottom points
        //     and are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal,
        //     but are not antialiased.
        LightDownwardDiagonal = 18,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the left from top points to bottom points
        //     and are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal,
        //     but they are not antialiased.
        LightUpwardDiagonal = 19,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the right from top points to bottom points,
        //     are spaced 50 percent closer together than, and are twice the width of System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal.
        //     This hatch pattern is not antialiased.
        DarkDownwardDiagonal = 20,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the left from top points to bottom points,
        //     are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal,
        //     and are twice its width, but the lines are not antialiased.
        DarkUpwardDiagonal = 21,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the right from top points to bottom points,
        //     have the same spacing as hatch style System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal,
        //     and are triple its width, but are not antialiased.
        WideDownwardDiagonal = 22,
        //
        // Summary:
        //     Specifies diagonal lines that slant to the left from top points to bottom points,
        //     have the same spacing as hatch style System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal,
        //     and are triple its width, but are not antialiased.
        WideUpwardDiagonal = 23,
        //
        // Summary:
        //     Specifies vertical lines that are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.Vertical.
        LightVertical = 24,
        //
        // Summary:
        //     Specifies horizontal lines that are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.Horizontal.
        LightHorizontal = 25,
        //
        // Summary:
        //     Specifies vertical lines that are spaced 75 percent closer together than hatch
        //     style System.Drawing.Drawing2D.HatchStyle.Vertical (or 25 percent closer together
        //     than System.Drawing.Drawing2D.HatchStyle.LightVertical).
        NarrowVertical = 26,
        //
        // Summary:
        //     Specifies horizontal lines that are spaced 75 percent closer together than hatch
        //     style System.Drawing.Drawing2D.HatchStyle.Horizontal (or 25 percent closer together
        //     than System.Drawing.Drawing2D.HatchStyle.LightHorizontal).
        NarrowHorizontal = 27,
        //
        // Summary:
        //     Specifies vertical lines that are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.Vertical
        //     and are twice its width.
        DarkVertical = 28,
        //
        // Summary:
        //     Specifies horizontal lines that are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.Horizontal
        //     and are twice the width of System.Drawing.Drawing2D.HatchStyle.Horizontal.
        DarkHorizontal = 29,
        //
        // Summary:
        //     Specifies dashed diagonal lines, that slant to the right from top points to bottom
        //     points.
        DashedDownwardDiagonal = 30,
        //
        // Summary:
        //     Specifies dashed diagonal lines, that slant to the left from top points to bottom
        //     points.
        DashedUpwardDiagonal = 31,
        //
        // Summary:
        //     Specifies dashed horizontal lines.
        DashedHorizontal = 32,
        //
        // Summary:
        //     Specifies dashed vertical lines.
        DashedVertical = 33,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of confetti.
        SmallConfetti = 34,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of confetti, and is composed of larger
        //     pieces than System.Drawing.Drawing2D.HatchStyle.SmallConfetti.
        LargeConfetti = 35,
        //
        // Summary:
        //     Specifies horizontal lines that are composed of zigzags.
        ZigZag = 36,
        //
        // Summary:
        //     Specifies horizontal lines that are composed of tildes.
        Wave = 37,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of layered bricks that slant to the
        //     left from top points to bottom points.
        DiagonalBrick = 38,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of horizontally layered bricks.
        HorizontalBrick = 39,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a woven material.
        Weave = 40,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a plaid material.
        Plaid = 41,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of divots.
        Divot = 42,
        //
        // Summary:
        //     Specifies horizontal and vertical lines, each of which is composed of dots, that
        //     cross.
        DottedGrid = 43,
        //
        // Summary:
        //     Specifies forward diagonal and backward diagonal lines, each of which is composed
        //     of dots, that cross.
        DottedDiamond = 44,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of diagonally layered shingles that
        //     slant to the right from top points to bottom points.
        Shingle = 45,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a trellis.
        Trellis = 46,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of spheres laid adjacent to one another.
        Sphere = 47,
        //
        // Summary:
        //     Specifies horizontal and vertical lines that cross and are spaced 50 percent
        //     closer together than hatch style System.Drawing.Drawing2D.HatchStyle.Cross.
        SmallGrid = 48,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a checkerboard.
        SmallCheckerBoard = 49,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a checkerboard with squares that
        //     are twice the size of System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard.
        LargeCheckerBoard = 50,
        //
        // Summary:
        //     Specifies forward diagonal and backward diagonal lines that cross but are not
        //     antialiased.
        OutlinedDiamond = 51,
        //
        // Summary:
        //     Specifies a hatch that has the appearance of a checkerboard placed diagonally.
        SolidDiamond = 52
    }
}
System.Drawing.Drawing2D.HatchStyle

4、绘制纹理填充矩形

 1 private void btnFillWithTextureBrush_Click(object sender, EventArgs e)
 2 {
 3     var rectangle = GetRandomRectangle();
 4 
 5     var wrapMode = (WrapMode)(random.Next(0, 5));
 6 
 7     var image = Icon.ToBitmap();
 8 
 9     using (var g = CreateGraphics())
10     using (var brush = new TextureBrush(image, wrapMode))
11     {
12         g.Clear(SystemColors.AppWorkspace);
13         g.SmoothingMode = SmoothingMode.HighQuality;
14         g.FillRectangle(brush, rectangle);
15     }
16 
17     ShowInformation($"纹理填充,{rectangle},WrapMode:{wrapMode}。");
18 }
纹理填充 —— btnFillWithTextureBrush_Click

纹理填充的关键在于对System.Drawing.TextureBrush这个画刷以及System.Drawing.Drawing2D.WrapMode的使用,

namespace System.Drawing
{
    //
    // Summary:
    //     Each property of the System.Drawing.TextureBrush class is a System.Drawing.Brush
    //     object that uses an image to fill the interior of a shape. This class cannot
    //     be inherited.
    public sealed class TextureBrush : Brush
    {
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image.
        //
        // Parameters:
        //   bitmap:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        public TextureBrush(Image bitmap);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image and wrap mode.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   wrapMode:
        //     A System.Drawing.Drawing2D.WrapMode enumeration that specifies how this System.Drawing.TextureBrush
        //     object is tiled.
        public TextureBrush(Image image, WrapMode wrapMode);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image and bounding rectangle.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   dstRect:
        //     A System.Drawing.RectangleF structure that represents the bounding rectangle
        //     for this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, RectangleF dstRect);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image and bounding rectangle.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   dstRect:
        //     A System.Drawing.Rectangle structure that represents the bounding rectangle for
        //     this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, Rectangle dstRect);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image, wrap mode, and bounding rectangle.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   wrapMode:
        //     A System.Drawing.Drawing2D.WrapMode enumeration that specifies how this System.Drawing.TextureBrush
        //     object is tiled.
        //
        //   dstRect:
        //     A System.Drawing.RectangleF structure that represents the bounding rectangle
        //     for this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, WrapMode wrapMode, RectangleF dstRect);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image, wrap mode, and bounding rectangle.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   wrapMode:
        //     A System.Drawing.Drawing2D.WrapMode enumeration that specifies how this System.Drawing.TextureBrush
        //     object is tiled.
        //
        //   dstRect:
        //     A System.Drawing.Rectangle structure that represents the bounding rectangle for
        //     this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, WrapMode wrapMode, Rectangle dstRect);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image, bounding rectangle, and image attributes.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   dstRect:
        //     A System.Drawing.RectangleF structure that represents the bounding rectangle
        //     for this System.Drawing.TextureBrush object.
        //
        //   imageAttr:
        //     An System.Drawing.Imaging.ImageAttributes object that contains additional information
        //     about the image used by this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, RectangleF dstRect, ImageAttributes imageAttr);
        //
        // Summary:
        //     Initializes a new System.Drawing.TextureBrush object that uses the specified
        //     image, bounding rectangle, and image attributes.
        //
        // Parameters:
        //   image:
        //     The System.Drawing.Image object with which this System.Drawing.TextureBrush object
        //     fills interiors.
        //
        //   dstRect:
        //     A System.Drawing.Rectangle structure that represents the bounding rectangle for
        //     this System.Drawing.TextureBrush object.
        //
        //   imageAttr:
        //     An System.Drawing.Imaging.ImageAttributes object that contains additional information
        //     about the image used by this System.Drawing.TextureBrush object.
        public TextureBrush(Image image, Rectangle dstRect, ImageAttributes imageAttr);

        //
        // Summary:
        //     Gets or sets a copy of the System.Drawing.Drawing2D.Matrix object that defines
        //     a local geometric transformation for the image associated with this System.Drawing.TextureBrush
        //     object.
        //
        // Returns:
        //     A copy of the System.Drawing.Drawing2D.Matrix object that defines a geometric
        //     transformation that applies only to fills drawn by using this System.Drawing.TextureBrush
        //     object.
        public Matrix Transform { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.WrapMode enumeration that indicates the
        //     wrap mode for this System.Drawing.TextureBrush object.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.WrapMode enumeration that specifies how fills drawn
        //     by using this System.Drawing.Drawing2D.LinearGradientBrush object are tiled.
        public WrapMode WrapMode { get; set; }
        //
        // Summary:
        //     Gets the System.Drawing.Image object associated with this System.Drawing.TextureBrush
        //     object.
        //
        // Returns:
        //     An System.Drawing.Image object that represents the image with which this System.Drawing.TextureBrush
        //     object fills shapes.
        public Image Image { get; }

        //
        // Summary:
        //     Creates an exact copy of this System.Drawing.TextureBrush object.
        //
        // Returns:
        //     The System.Drawing.TextureBrush object this method creates, cast as an System.Object
        //     object.
        public override object Clone();
        //
        // Summary:
        //     Multiplies the System.Drawing.Drawing2D.Matrix object that represents the local
        //     geometric transformation of this System.Drawing.TextureBrush object by the specified
        //     System.Drawing.Drawing2D.Matrix object in the specified order.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix object by which to multiply the geometric
        //     transformation.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder enumeration that specifies the order in
        //     which to multiply the two matrices.
        public void MultiplyTransform(Matrix matrix, MatrixOrder order);
        //
        // Summary:
        //     Multiplies the System.Drawing.Drawing2D.Matrix object that represents the local
        //     geometric transformation of this System.Drawing.TextureBrush object by the specified
        //     System.Drawing.Drawing2D.Matrix object by prepending the specified System.Drawing.Drawing2D.Matrix
        //     object.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix object by which to multiply the geometric
        //     transformation.
        public void MultiplyTransform(Matrix matrix);
        //
        // Summary:
        //     Resets the Transform property of this System.Drawing.TextureBrush object to identity.
        public void ResetTransform();
        //
        // Summary:
        //     Rotates the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified amount. This method prepends the rotation to the transformation.
        //
        // Parameters:
        //   angle:
        //     The angle of rotation.
        public void RotateTransform(float angle);
        //
        // Summary:
        //     Rotates the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified amount in the specified order.
        //
        // Parameters:
        //   angle:
        //     The angle of rotation.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder enumeration that specifies whether to
        //     append or prepend the rotation matrix.
        public void RotateTransform(float angle, MatrixOrder order);
        //
        // Summary:
        //     Scales the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified amounts. This method prepends the scaling matrix to the
        //     transformation.
        //
        // Parameters:
        //   sx:
        //     The amount by which to scale the transformation in the x direction.
        //
        //   sy:
        //     The amount by which to scale the transformation in the y direction.
        public void ScaleTransform(float sx, float sy);
        //
        // Summary:
        //     Scales the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified amounts in the specified order.
        //
        // Parameters:
        //   sx:
        //     The amount by which to scale the transformation in the x direction.
        //
        //   sy:
        //     The amount by which to scale the transformation in the y direction.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder enumeration that specifies whether to
        //     append or prepend the scaling matrix.
        public void ScaleTransform(float sx, float sy, MatrixOrder order);
        //
        // Summary:
        //     Translates the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified dimensions. This method prepends the translation to the
        //     transformation.
        //
        // Parameters:
        //   dx:
        //     The dimension by which to translate the transformation in the x direction.
        //
        //   dy:
        //     The dimension by which to translate the transformation in the y direction.
        public void TranslateTransform(float dx, float dy);
        //
        // Summary:
        //     Translates the local geometric transformation of this System.Drawing.TextureBrush
        //     object by the specified dimensions in the specified order.
        //
        // Parameters:
        //   dx:
        //     The dimension by which to translate the transformation in the x direction.
        //
        //   dy:
        //     The dimension by which to translate the transformation in the y direction.
        //
        //   order:
        //     The order (prepend or append) in which to apply the translation.
        public void TranslateTransform(float dx, float dy, MatrixOrder order);
    }
}
System.Drawing.TextureBrush
namespace System.Drawing.Drawing2D
{
    //
    // Summary:
    //     Specifies how a texture or gradient is tiled when it is smaller than the area
    //     being filled.
    public enum WrapMode
    {
        //
        // Summary:
        //     Tiles the gradient or texture.
        Tile = 0,
        //
        // Summary:
        //     Reverses the texture or gradient horizontally and then tiles the texture or gradient.
        TileFlipX = 1,
        //
        // Summary:
        //     Reverses the texture or gradient vertically and then tiles the texture or gradient.
        TileFlipY = 2,
        //
        // Summary:
        //     Reverses the texture or gradient horizontally and vertically and then tiles the
        //     texture or gradient.
        TileFlipXY = 3,
        //
        // Summary:
        //     The texture or gradient is not tiled.
        Clamp = 4
    }
}
System.Drawing.Drawing2D.WrapMode

TextureBrush这个画刷的主要成分是Image,由于我们还没接触Image,这里就简单实现一下使用范例,等以后对Image有足够的了解,这个画刷也就非常简单了。本示例就简单的将窗体的Icon作为Image使用了。

5、绘制路径过渡填充矩形

 1 private void btnFillWithPathGradientBrush_Click(object sender, EventArgs e)
 2 {
 3     var rectangle = GetRandomRectangle();
 4 
 5     var wrapMode = (WrapMode)(random.Next(0, 5));
 6 
 7     var points = new Point[] { GetRandomPoint(), GetRandomPoint(), GetRandomPoint(), GetRandomPoint(), GetRandomPoint() };
 8 
 9     using (var g = CreateGraphics())
10     using (var pen = new Pen(penColor, 2f))
11     using (var brush = new PathGradientBrush(points, wrapMode))
12     {
13         g.Clear(SystemColors.AppWorkspace);
14         g.SmoothingMode = SmoothingMode.HighQuality;
15         g.DrawRectangle(pen, rectangle);
16         g.FillRectangle(brush, rectangle);
17     }
18 
19     ShowInformation($"路径填充,{rectangle},WrapMode:{wrapMode}。");
20 }
路径填充 —— btnFillWithPathGradientBrush_Click

路径过渡填充的关键在于对System.Drawing.Drawing2D.PathGradientBrush的使用以及与纹理填充一样的WrapMode。

namespace System.Drawing.Drawing2D
{
    //
    // Summary:
    //     Encapsulates a System.Drawing.Brush object that fills the interior of a System.Drawing.Drawing2D.GraphicsPath
    //     object with a gradient. This class cannot be inherited.
    public sealed class PathGradientBrush : Brush
    {
        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.PathGradientBrush
        //     class with the specified points.
        //
        // Parameters:
        //   points:
        //     An array of System.Drawing.PointF structures that represents the points that
        //     make up the vertices of the path.
        public PathGradientBrush(PointF[] points);
        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.PathGradientBrush
        //     class with the specified points.
        //
        // Parameters:
        //   points:
        //     An array of System.Drawing.Point structures that represents the points that make
        //     up the vertices of the path.
        public PathGradientBrush(Point[] points);
        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.PathGradientBrush
        //     class with the specified path.
        //
        // Parameters:
        //   path:
        //     The System.Drawing.Drawing2D.GraphicsPath that defines the area filled by this
        //     System.Drawing.Drawing2D.PathGradientBrush.
        public PathGradientBrush(GraphicsPath path);
        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.PathGradientBrush
        //     class with the specified points and wrap mode.
        //
        // Parameters:
        //   points:
        //     An array of System.Drawing.PointF structures that represents the points that
        //     make up the vertices of the path.
        //
        //   wrapMode:
        //     A System.Drawing.Drawing2D.WrapMode that specifies how fills drawn with this
        //     System.Drawing.Drawing2D.PathGradientBrush are tiled.
        public PathGradientBrush(PointF[] points, WrapMode wrapMode);
        //
        // Summary:
        //     Initializes a new instance of the System.Drawing.Drawing2D.PathGradientBrush
        //     class with the specified points and wrap mode.
        //
        // Parameters:
        //   points:
        //     An array of System.Drawing.Point structures that represents the points that make
        //     up the vertices of the path.
        //
        //   wrapMode:
        //     A System.Drawing.Drawing2D.WrapMode that specifies how fills drawn with this
        //     System.Drawing.Drawing2D.PathGradientBrush are tiled.
        public PathGradientBrush(Point[] points, WrapMode wrapMode);

        //
        // Summary:
        //     Gets or sets a copy of the System.Drawing.Drawing2D.Matrix that defines a local
        //     geometric transform for this System.Drawing.Drawing2D.PathGradientBrush.
        //
        // Returns:
        //     A copy of the System.Drawing.Drawing2D.Matrix that defines a geometric transform
        //     that applies only to fills drawn with this System.Drawing.Drawing2D.PathGradientBrush.
        public Matrix Transform { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.ColorBlend that defines a multicolor
        //     linear gradient.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.ColorBlend that defines a multicolor linear gradient.
        public ColorBlend InterpolationColors { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.Blend that specifies positions and factors
        //     that define a custom falloff for the gradient.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.Blend that represents a custom falloff for the gradient.
        public Blend Blend { get; set; }
        //
        // Summary:
        //     Gets a bounding rectangle for this System.Drawing.Drawing2D.PathGradientBrush.
        //
        // Returns:
        //     A System.Drawing.RectangleF that represents a rectangular region that bounds
        //     the path this System.Drawing.Drawing2D.PathGradientBrush fills.
        public RectangleF Rectangle { get; }
        //
        // Summary:
        //     Gets or sets the center point of the path gradient.
        //
        // Returns:
        //     A System.Drawing.PointF that represents the center point of the path gradient.
        public PointF CenterPoint { get; set; }
        //
        // Summary:
        //     Gets or sets an array of colors that correspond to the points in the path this
        //     System.Drawing.Drawing2D.PathGradientBrush fills.
        //
        // Returns:
        //     An array of System.Drawing.Color structures that represents the colors associated
        //     with each point in the path this System.Drawing.Drawing2D.PathGradientBrush fills.
        public Color[] SurroundColors { get; set; }
        //
        // Summary:
        //     Gets or sets the color at the center of the path gradient.
        //
        // Returns:
        //     A System.Drawing.Color that represents the color at the center of the path gradient.
        public Color CenterColor { get; set; }
        //
        // Summary:
        //     Gets or sets the focus point for the gradient falloff.
        //
        // Returns:
        //     A System.Drawing.PointF that represents the focus point for the gradient falloff.
        public PointF FocusScales { get; set; }
        //
        // Summary:
        //     Gets or sets a System.Drawing.Drawing2D.WrapMode that indicates the wrap mode
        //     for this System.Drawing.Drawing2D.PathGradientBrush.
        //
        // Returns:
        //     A System.Drawing.Drawing2D.WrapMode that specifies how fills drawn with this
        //     System.Drawing.Drawing2D.PathGradientBrush are tiled.
        public WrapMode WrapMode { get; set; }

        //
        // Summary:
        //     Creates an exact copy of this System.Drawing.Drawing2D.PathGradientBrush.
        //
        // Returns:
        //     The System.Drawing.Drawing2D.PathGradientBrush this method creates, cast as an
        //     object.
        public override object Clone();
        //
        // Summary:
        //     Updates the brush's transformation matrix with the product of brush's transformation
        //     matrix multiplied by another matrix.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix that will be multiplied by the brush's current
        //     transformation matrix.
        public void MultiplyTransform(Matrix matrix);
        //
        // Summary:
        //     Updates the brush's transformation matrix with the product of the brush's transformation
        //     matrix multiplied by another matrix.
        //
        // Parameters:
        //   matrix:
        //     The System.Drawing.Drawing2D.Matrix that will be multiplied by the brush's current
        //     transformation matrix.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies in which order to multiply
        //     the two matrices.
        public void MultiplyTransform(Matrix matrix, MatrixOrder order);
        //
        // Summary:
        //     Resets the System.Drawing.Drawing2D.PathGradientBrush.Transform property to identity.
        public void ResetTransform();
        //
        // Summary:
        //     Rotates the local geometric transform by the specified amount. This method prepends
        //     the rotation to the transform.
        //
        // Parameters:
        //   angle:
        //     The angle (extent) of rotation.
        public void RotateTransform(float angle);
        //
        // Summary:
        //     Rotates the local geometric transform by the specified amount in the specified
        //     order.
        //
        // Parameters:
        //   angle:
        //     The angle (extent) of rotation.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies whether to append or prepend
        //     the rotation matrix.
        public void RotateTransform(float angle, MatrixOrder order);
        //
        // Summary:
        //     Scales the local geometric transform by the specified amounts. This method prepends
        //     the scaling matrix to the transform.
        //
        // Parameters:
        //   sx:
        //     The transform scale factor in the x-axis direction.
        //
        //   sy:
        //     The transform scale factor in the y-axis direction.
        public void ScaleTransform(float sx, float sy);
        //
        // Summary:
        //     Scales the local geometric transform by the specified amounts in the specified
        //     order.
        //
        // Parameters:
        //   sx:
        //     The transform scale factor in the x-axis direction.
        //
        //   sy:
        //     The transform scale factor in the y-axis direction.
        //
        //   order:
        //     A System.Drawing.Drawing2D.MatrixOrder that specifies whether to append or prepend
        //     the scaling matrix.
        public void ScaleTransform(float sx, float sy, MatrixOrder order);
        //
        // Summary:
        //     Creates a gradient with a center color and a linear falloff to each surrounding
        //     color.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies where, along any radial from the center
        //     of the path to the path's boundary, the center color will be at its highest intensity.
        //     A value of 1 (the default) places the highest intensity at the center of the
        //     path.
        //
        //   scale:
        //     A value from 0 through 1 that specifies the maximum intensity of the center color
        //     that gets blended with the boundary color. A value of 1 causes the highest possible
        //     intensity of the center color, and it is the default value.
        public void SetBlendTriangularShape(float focus, float scale);
        //
        // Summary:
        //     Creates a gradient with a center color and a linear falloff to one surrounding
        //     color.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies where, along any radial from the center
        //     of the path to the path's boundary, the center color will be at its highest intensity.
        //     A value of 1 (the default) places the highest intensity at the center of the
        //     path.
        public void SetBlendTriangularShape(float focus);
        //
        // Summary:
        //     Creates a gradient brush that changes color starting from the center of the path
        //     outward to the path's boundary. The transition from one color to another is based
        //     on a bell-shaped curve.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies where, along any radial from the center
        //     of the path to the path's boundary, the center color will be at its highest intensity.
        //     A value of 1 (the default) places the highest intensity at the center of the
        //     path.
        //
        //   scale:
        //     A value from 0 through 1 that specifies the maximum intensity of the center color
        //     that gets blended with the boundary color. A value of 1 causes the highest possible
        //     intensity of the center color, and it is the default value.
        public void SetSigmaBellShape(float focus, float scale);
        //
        // Summary:
        //     Creates a gradient brush that changes color starting from the center of the path
        //     outward to the path's boundary. The transition from one color to another is based
        //     on a bell-shaped curve.
        //
        // Parameters:
        //   focus:
        //     A value from 0 through 1 that specifies where, along any radial from the center
        //     of the path to the path's boundary, the center color will be at its highest intensity.
        //     A value of 1 (the default) places the highest intensity at the center of the
        //     path.
        public void SetSigmaBellShape(float focus);
        //
        // Summary:
        //     Applies the specified translation to the local geometric transform in the specified
        //     order.
        //
        // Parameters:
        //   dx:
        //     The value of the translation in x.
        //
        //   dy:
        //     The value of the translation in y.
        //
        //   order:
        //     The order (prepend or append) in which to apply the translation.
        public void TranslateTransform(float dx, float dy, MatrixOrder order);
        //
        // Summary:
        //     Applies the specified translation to the local geometric transform. This method
        //     prepends the translation to the transform.
        //
        // Parameters:
        //   dx:
        //     The value of the translation in x.
        //
        //   dy:
        //     The value of the translation in y.
        public void TranslateTransform(float dx, float dy);
    }
}
System.Drawing.Drawing2D.PathGradientBrush

从它的构造函数可以看出,其实它就是需要指定一些关键点,有了这些点,它就可以构造一个GraphicsPath,路径可以作为矢量的描述,也就是通常说的放大、缩小不失真。

本例中取了几个随机点,所以,填充看起来,比较抽象……

好了,到这里呢,关于矩形的基本画法就已经全部介绍完了,感觉有点EZ? BORED?那么我们就来利用现有的知识,再来耍个花活?

6、绘制会浮动的变色魔法箱

 1 private Rectangle magicRectangle = Rectangle.Empty;
 2 enum Directions : short { UP = 1, RIGHT = 2, DOWN = 4, LEFT = 8, };
 3 private Directions direction = Directions.UP | Directions.RIGHT;
 4 private Color magicColor = Color.FromArgb(0, 0, 255);
 5 private int increament = 1;
 6 
 7 private void btnMagicBox_Click(object sender, EventArgs e)
 8 {
 9     direction = Directions.UP | Directions.RIGHT;
10 
11     magicRectangle = GetRandomRectangle();
12 
13     using (var g = CreateGraphics())
14         g.Clear(SystemColors.AppWorkspace);
15 
16     timer.Enabled = !timer.Enabled;
17 
18     ShowInformation($"魔法箱,开始:{timer.Enabled}。");
19 }
20 
21 private void timer_Tick(object sender, EventArgs e)
22 {
23     using (var g = CreateGraphics())
24     using (var brush = new SolidBrush(magicColor))
25     {
26         g.FillRectangle(new SolidBrush(SystemColors.AppWorkspace), magicRectangle);
27 
28         magicColor = Color.FromArgb(magicColor.R + increament, magicColor.G + increament, magicColor.B - increament);
29         if (0 == magicColor.R || 255 == magicColor.R) increament = -increament;
30 
31         if (magicRectangle.Top <= ClientRectangle.Top && Directions.UP == (direction & Directions.UP))
32             direction = direction ^ Directions.UP | Directions.DOWN;
33 
34         if (magicRectangle.Left <= ClientRectangle.Left && Directions.LEFT == (direction & Directions.LEFT))
35             direction = direction ^ Directions.LEFT | Directions.RIGHT;
36 
37         if (magicRectangle.Right >= ClientRectangle.Right && Directions.RIGHT == (direction & Directions.RIGHT))
38             direction = direction ^ Directions.RIGHT | Directions.LEFT;
39 
40         if (magicRectangle.Bottom >= ClientRectangle.Bottom - pnlToolbox.Height && Directions.DOWN == (direction & Directions.DOWN))
41             direction = direction ^ Directions.DOWN | Directions.UP;
42 
43         if (Directions.UP == (direction & Directions.UP)) magicRectangle.Offset(0, -3);
44         if (Directions.LEFT == (direction & Directions.LEFT)) magicRectangle.Offset(-3, 0);
45         if (Directions.RIGHT == (direction & Directions.RIGHT)) magicRectangle.Offset(3, 0);
46         if (Directions.DOWN == (direction & Directions.DOWN)) magicRectangle.Offset(0, 3);
47 
48         g.FillRectangle(brush, magicRectangle);
49     }
50 
51 }
魔法箱 —— btnMagicBox_Click

原理也不复杂,点击“魔法箱”按钮,获取一个随机Rectangle赋值给magicRectangle,切换timer组件的Enable。在timer_Tick事件中,做五件事:

  1. 将magicRectangle的当前位置填充成背景色;
  2. 获取一个变化的颜色,为了使颜色不那么跳跃,这里对magicColor的变化作了一些手脚;
  3. 做碰撞检测,以改变箱子的运动方向;
  4. 根据箱子的运动方向,用Rectangle.Offset()方法修改矩形的位置;
  5. 为矩形填充magicColor;

由于截图也看不出动态效果,就不上图了,有兴趣的童鞋可以Run代码看看效果:)

Okay,关于GDI+画矩形的部分,我们就到此告一段落了。

其实说了半天,也没多复杂,基本方法就是Graphics.FillRectangle(Brush brush, Rectangle rect),区别就在于我们如何构造一个合适的Brush。

喜欢本系列丛书的朋友,可以点击链接加入QQ交流群(994761602)【C# 破境之道】
方便各位在有疑问的时候可以及时给我个反馈。同时,也算是给各位志同道合的朋友提供一个交流的平台。
需要源码的童鞋,也可以在群文件中获取最新源代码。

原文地址:https://www.cnblogs.com/mikecheers/p/12334166.html