原文: http://zetcode.com/gui/csharpwinforms/painting/

在 Mono Winforms 教程的这一部分中,我们将进行绘图。 当我们想要更改或增强现有控件时,将使用绘图。 或者,如果我们要从头开始创建自定义控件。 要进行绘图,我们使用 Winforms 库提供的绘图 API。 绘图是在一种方法中完成的,我们将其插入Paint事件。

System.Drawing名称空间提供对GDI+基本图形功能的访问。 System.Drawing.Drawing2DSystem.Drawing.ImagingSystem.Drawing.Text命名空间中提供了更高级的功能。 Graphics类提供了在表单上绘图的方法。

直线

我们的第一个示例将在Form控件上绘制线条。

lines.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. class MForm : Form {
  6. public MForm() {
  7. Text = "Lines";
  8. Size = new Size(280, 270);
  9. ResizeRedraw = true;
  10. Paint += new PaintEventHandler(OnPaint);
  11. CenterToScreen();
  12. }
  13. void OnPaint(object sender, PaintEventArgs e)
  14. {
  15. Graphics g = e.Graphics;
  16. Pen pen = new Pen(Color.Black, 1);
  17. pen.DashStyle = DashStyle.Dot;
  18. g.DrawLine(pen, 20, 40, 250, 40);
  19. pen.DashStyle = DashStyle.DashDot;
  20. g.DrawLine(pen, 20, 80, 250, 80);
  21. pen.DashStyle = DashStyle.Dash;
  22. g.DrawLine(pen, 20, 120, 250, 120);
  23. pen.DashStyle = DashStyle.DashDotDot;
  24. g.DrawLine(pen, 20, 160, 250, 160);
  25. pen.DashPattern = new float[] {6f, 8f, 1f, 1f, 1f, 1f, 1f, 1f };
  26. g.DrawLine(pen, 20, 200, 250, 200);
  27. g.Dispose();
  28. }
  29. }
  30. class MApplication {
  31. public static void Main() {
  32. Application.Run(new MForm());
  33. }
  34. }

我们在表格上画了五行。 每行具有不同的DashStyle

  1. ResizeRedraw = true;

调整表单大小时,它会自动重绘。 这不是默认行为。

  1. Paint += new PaintEventHandler(OnPaint);

绘图事件将传递给OnPaint()方法。

  1. void OnPaint(object sender, PaintEventArgs e)
  2. {
  3. ...
  4. }

这是OnPaint()方法的签名。

  1. Graphics g = e.Graphics;

为了在表单上绘图,我们必须获取Graphics对象。 在窗体上绘图实际上是在调用Graphics对象的各种方法。

  1. Pen pen = new Pen(Color.Black, 1);
  2. pen.DashStyle = DashStyle.Dot;
  3. g.DrawLine(pen, 20, 40, 250, 40);

我们创建一个Pen对象。 该对象用于绘制形状的轮廓。 比我们设置点划线DashStyle。 最后,我们用DrawLine()方法画线。 第一个参数是钢笔对象。 接下来的四个值是线的起点和终点的 x 和 y 值。

  1. pen.DashPattern = new float[] {6f, 8f, 1f, 1f, 1f, 1f, 1f, 1f };

有几个内置的DashStyle值。 我们可以使用DashPattern属性来创建自己的样式。 乍一看可能很难。 但是模式只是填充和空值的数组。

  1. g.Dispose();

我们知道 C# 语言使用垃圾回收。 那么,为什么我们要明确释放资源? 这是为了提高效率。 我们正在帮助垃圾收集器。

Mono Winforms 中的绘图 - 图1

图:直线

色彩

Winforms 库中的颜色表示 ARGB(alpha,红色,绿色,蓝色)颜色。 它是 Alpha,红色,绿色和蓝色(RGB)强度值的组合。 还有一些可以在绘图中使用的预定义颜色名称。

colors.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. class MForm : Form {
  6. public MForm() {
  7. Text = "Colors";
  8. Size = new Size(360, 300);
  9. Paint += new PaintEventHandler(OnPaint);
  10. CenterToScreen();
  11. }
  12. void OnPaint(object sender, PaintEventArgs e)
  13. {
  14. Graphics g = e.Graphics;
  15. g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60);
  16. g.FillRectangle(Brushes.Green, 130, 15, 90, 60);
  17. g.FillRectangle(Brushes.Maroon, 250, 15, 90, 60);
  18. g.FillRectangle(Brushes.Chocolate, 10, 105, 90, 60);
  19. g.FillRectangle(Brushes.Gray, 130, 105, 90, 60);
  20. g.FillRectangle(Brushes.Coral, 250, 105, 90, 60);
  21. g.FillRectangle(Brushes.Brown, 10, 195, 90, 60);
  22. g.FillRectangle(Brushes.Teal, 130, 195, 90, 60);
  23. g.FillRectangle(Brushes.Goldenrod, 250, 195, 90, 60);
  24. g.Dispose();
  25. }
  26. }
  27. class MApplication {
  28. public static void Main() {
  29. Application.Run(new MForm());
  30. }
  31. }

我们用 9 种不同的颜色绘制 9 个矩形。

  1. g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60);

FillRectagle()方法用画笔填充指定的矩形。 画笔可以是颜色或图案。 有一些预定义的颜色可用。 我们可以从Brushes枚举中获取它们。 最后四个值是左上角点的 x,y 值以及矩形的宽度和高度。

Mono Winforms 中的绘图 - 图2

图:颜色

HatchBrush

HatchBrush对象用于填充形状的内部。 我们可以使用几种内置模式。

hatches.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. class MForm : Form {
  6. public MForm() {
  7. Text = "Hatches";
  8. Size = new Size(360, 300);
  9. Paint += new PaintEventHandler(OnPaint);
  10. CenterToScreen();
  11. }
  12. void OnPaint(object sender, PaintEventArgs e)
  13. {
  14. Graphics g = e.Graphics;
  15. HatchBrush hb = new HatchBrush(HatchStyle.Cross, Color.Black, this.BackColor);
  16. g.FillRectangle(hb, 10, 15, 90, 60);
  17. hb = new HatchBrush(HatchStyle.Percent05, Color.Black, this.BackColor);
  18. g.FillRectangle(hb, 130, 15, 90, 60);
  19. hb = new HatchBrush(HatchStyle.SolidDiamond, Color.Black, this.BackColor);
  20. g.FillRectangle(hb, 250, 15, 90, 60);
  21. hb = new HatchBrush(HatchStyle.DiagonalBrick, Color.Black, this.BackColor);
  22. g.FillRectangle(hb, 10, 105, 90, 60);
  23. hb = new HatchBrush(HatchStyle.Divot, Color.Black, this.BackColor);
  24. g.FillRectangle(hb, 130, 105, 90, 60);
  25. hb = new HatchBrush(HatchStyle.Wave, Color.Black, this.BackColor);
  26. g.FillRectangle(hb, 250, 105, 90, 60);
  27. hb = new HatchBrush(HatchStyle.ZigZag, Color.Black, this.BackColor);
  28. g.FillRectangle(hb, 10, 195, 90, 60);
  29. hb = new HatchBrush(HatchStyle.Sphere, Color.Black, this.BackColor);
  30. g.FillRectangle(hb, 130, 195, 90, 60);
  31. hb = new HatchBrush(HatchStyle.Shingle, Color.Black, this.BackColor);
  32. g.FillRectangle(hb, 250, 195, 90, 60);
  33. hb.Dispose();
  34. g.Dispose();
  35. }
  36. }
  37. class MApplication {
  38. public static void Main() {
  39. Application.Run(new MForm());
  40. }
  41. }

这次,我们用九种不同的图案(称为剖面线)填充了九个矩形。

  1. HatchBrush hb = new HatchBrush(HatchStyle.Cross, Color.Black, this.BackColor);

在这里,我们创建一个HatchBrush对象。 参数是图案填充样式以及前景色和背景色。 背景颜色设置为表单的颜色,因此看起来就像我们在表单上绘制的一样。

  1. g.FillRectangle(hb, 10, 15, 90, 60);

我们使用指定的阴影刷填充矩形。

Mono Winforms 中的绘图 - 图3

图:通口

渐变

在计算机图形学中,渐变是从浅到深或从一种颜色到另一种颜色的阴影的平滑混合。 在 2D 绘图程序和绘图程序中,渐变用于创建彩色背景和特殊效果以及模拟灯光和阴影。 (answers.com)

gradients.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. class MForm : Form {
  6. public MForm() {
  7. Text = "Gradients";
  8. Size = new Size(350, 350);
  9. Paint += new PaintEventHandler(OnPaint);
  10. CenterToScreen();
  11. }
  12. void OnPaint(object sender, PaintEventArgs e)
  13. {
  14. Graphics g = e.Graphics;
  15. Point pt1 = new Point(5, 5);
  16. Point pt2 = new Point(25, 25);
  17. Brush lg = new LinearGradientBrush(pt1, pt2, Color.Red, Color.Black);
  18. g.FillRectangle(lg, 20, 20, 300, 40);
  19. pt1 = new Point(5, 25);
  20. pt2 = new Point(20, 2);
  21. lg = new LinearGradientBrush(pt1, pt2, Color.Yellow, Color.Black);
  22. g.FillRectangle(lg, 20, 80, 300, 40);
  23. pt1 = new Point(5, 25);
  24. pt2 = new Point(2, 2);
  25. lg = new LinearGradientBrush(pt1, pt2, Color.Green, Color.Black);
  26. g.FillRectangle(lg, 20, 140, 300, 40);
  27. pt1 = new Point(25, 25);
  28. pt2 = new Point(15, 25);
  29. lg = new LinearGradientBrush(pt1, pt2, Color.Blue, Color.Black);
  30. g.FillRectangle(lg, 20, 200, 300, 40);
  31. pt1 = new Point(0, 10);
  32. pt2 = new Point(0, 20);
  33. lg = new LinearGradientBrush(pt1, pt2, Color.Orange, Color.Black);
  34. g.FillRectangle(lg, 20, 260, 300, 40);
  35. lg.Dispose();
  36. g.Dispose();
  37. }
  38. }
  39. class MApplication {
  40. public static void Main() {
  41. Application.Run(new MForm());
  42. }
  43. }

我们绘制五个矩形,这些矩形填充有不同的线性渐变。

  1. Point pt1 = new Point(5, 5);
  2. Point pt2 = new Point(25, 25);

这两个是线性渐变画笔的控制点。

  1. Brush lg = new LinearGradientBrush(pt1, pt2, Color.Red, Color.Black);

我们创建LinearGradientBrush对象。 我们使用两个控制点和两种混合颜色。

Mono Winforms 中的绘图 - 图4

图:渐变

画线

要在 Winforms Form上绘制字符串,我们使用DrawString()方法。

lyrics.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. class MForm : Form {
  6. public MForm() {
  7. Text = "You know I'm No Good";
  8. Size = new Size(380, 450);
  9. Paint += new PaintEventHandler(OnPaint);
  10. CenterToScreen();
  11. }
  12. void OnPaint(object sender, PaintEventArgs e)
  13. {
  14. Graphics g = e.Graphics;
  15. Font ft = new Font("Purisa", 10);
  16. SolidBrush br = new SolidBrush(Color.Black);
  17. PointF pt = new PointF(20.0f, 20.0f);
  18. g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt);
  19. pt = new PointF(20.0f, 50.0f);
  20. g.DrawString("Your rolled up sleeves and your skull t-shirt", ft, br, pt);
  21. pt = new PointF(20.0f, 80.0f);
  22. g.DrawString("You say why did you do it with him today?", ft, br, pt);
  23. pt = new PointF(20.0f, 110.0f);
  24. g.DrawString("And sniffed me out like I was tanqueray", ft, br, pt);
  25. pt = new PointF(20.0f, 160.0f);
  26. g.DrawString("Cause you’re my fella, my guy", ft, br, pt);
  27. pt = new PointF(20.0f, 190.0f);
  28. g.DrawString("Hand me your stella and fly", ft, br, pt);
  29. pt = new PointF(20.0f, 220.0f);
  30. g.DrawString("By the time I’m out the door", ft, br, pt);
  31. pt = new PointF(20.0f, 250.0f);
  32. g.DrawString("You tear me down like roger moore", ft, br, pt);
  33. pt = new PointF(20.0f, 300.0f);
  34. g.DrawString("I cheated myself", ft, br, pt);
  35. pt = new PointF(20.0f, 330.0f);
  36. g.DrawString("Like I knew I would", ft, br, pt);
  37. pt = new PointF(20.0f, 360.0f);
  38. g.DrawString("I told ya, I was trouble", ft, br, pt);
  39. pt = new PointF(20.0f, 390.0f);
  40. g.DrawString("You know that I’m no good", ft, br, pt);
  41. g.Dispose();
  42. }
  43. }
  44. class MApplication {
  45. public static void Main() {
  46. Application.Run(new MForm());
  47. }
  48. }

在我们的示例中,我们在 Winforms 窗体上绘制歌曲的歌词。

  1. Font ft = new Font("Purisa", 10);

我们使用 10 磅高的 Purisa 字体。

  1. PointF pt = new PointF(20.0f, 20.0f);

要在表单上绘制字符串,我们必须使用浮点值。

  1. g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt);

DrawString()方法采用以下参数:要绘制的文本,字体,笔刷和PointF对象。

Mono Winforms 中的绘图 - 图5

图:歌词

绘制图像

在最后一个示例中,我们将在Form控件上绘制图像。

redrock.cs

  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4. class MForm : Form {
  5. private Bitmap castle;
  6. public MForm() {
  7. Text = "Red Rock";
  8. loadImage();
  9. ClientSize = new Size(castle.Width, castle.Height);
  10. Paint += new PaintEventHandler(OnPaint);
  11. CenterToScreen();
  12. }
  13. void loadImage() {
  14. try {
  15. castle = new Bitmap("redrock.png");
  16. } catch (Exception e) {
  17. Console.WriteLine(e.Message);
  18. Environment.Exit(1);
  19. }
  20. }
  21. void OnPaint(object sender, PaintEventArgs e)
  22. {
  23. Graphics g = e.Graphics;
  24. Rectangle r = new Rectangle(1, 1, castle.Width, castle.Height);
  25. g.DrawImage(castle, r);
  26. }
  27. }
  28. class MApplication {
  29. public static void Main() {
  30. Application.Run(new MForm());
  31. }
  32. }

此代码示例在窗体上绘制城堡的图像。

  1. try {
  2. castle = new Bitmap("redrock.png");
  3. } catch (Exception e) {
  4. Console.WriteLine(e.Message);
  5. Environment.Exit(1);
  6. }

我们加载城堡的图像。

  1. Rectangle r = new Rectangle(1, 1, castle.Width, castle.Height);

我们确定将要绘制的矩形。

  1. g.DrawImage(castle, r);

这条线实际上绘制图像。

Mono Winforms 中的绘图 - 图6

图:图像

在本章中,我们在 Mono Winforms 库中做了一些绘图。