翼度科技»论坛 编程开发 .net 查看内容

C#自定义控件—流动管道

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
C#用户控件之流动管道

如何绘制一个动态的流动管道(FlowPipe)?

分两步绘制

  • 定义属性;
  • 画布重绘;
主要技能:

  • 管道的绘制(渐变色矩形)
  1.   /// <summary>
  2.   /// 画渐变色矩形的方法
  3.   /// </summary>
  4.   /// <param name="g">画布</param>
  5.   /// <param name="brush">画刷</param>
  6.   /// <param name="pen">笔</param>
  7.   /// <param name="rectangle">矩形</param>
  8.   private void PaintRectangle(Graphics g, Brush brush, Pen pen, Rectangle rectangle)
  9.   {
  10.       //填充矩形
  11.       g.FillRectangle(brush, rectangle);
  12.       switch (this.pipeStyle)
  13.       {
  14.           case PipeStyle.Horizontal:
  15.               g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y);
  16.               g.DrawLine(pen, rectangle.X, rectangle.Y + rectangle.Height - 1, rectangle.X + rectangle.Width, rectangle.Height);
  17.               break;
  18.           case PipeStyle.Vertical:
  19.               g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + rectangle.Height);
  20.               g.DrawLine(pen, rectangle.X + rectangle.Width - 1, rectangle.Y, rectangle.X + rectangle.Width - 1, rectangle.Height);
  21.               break;
  22.           default:
  23.               break;
  24.       }
  25.   }
复制代码

  • 管道的绘制(渐变色半圆)
  1. /// <summary>
  2. /// 画渐变色半圆的方法
  3. /// </summary>
  4. /// <param name="g">画布</param>
  5. /// <param name="colorBlend"></param>
  6. /// <param name="p"></param>
  7. /// <param name="rect"></param>
  8. /// <param name="startAngle"></param>
  9. /// <param name="sweepAngle"></param>
  10. private void PaintEllipse(Graphics g, ColorBlend colorBlend, Pen p, Rectangle rect, float startAngle, float sweepAngle)
  11. {
  12.     //第一步:创建GPI路径
  13.     GraphicsPath path = new GraphicsPath();
  14.     path.AddEllipse(rect);
  15.     //第二步:渐变色填充
  16.     PathGradientBrush brush = new PathGradientBrush(path);
  17.     brush.CenterPoint = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
  18.     brush.InterpolationColors = colorBlend;
  19.     //第三步:绘制管道
  20.     g.FillPie(brush, rect, startAngle, sweepAngle);
  21.     //第四步:绘制边线
  22.     g.DrawArc(p, rect, startAngle, sweepAngle);
  23. }
复制代码

  • 流动条的绘制(用笔的虚线)
  1. //画虚线,关键用笔和路径来画
  2. Pen pen = new Pen(this.flowColor, this.flowWidth);
  3. pen.DashStyle = DashStyle.Custom;
  4. pen.DashPattern = new float[]
  5. {
  6.     flowLength,flowLengthGap
  7. };
  8. pen.DashOffset = this.startOffset;
  9. g.DrawPath(pen, path);
  10. //流动条路径
  11. GraphicsPath path = new GraphicsPath();
  12. //虚线路径—左边、中间、右边
  13. switch (this.pipeTurnLeft)
  14. {
  15.      case PipeTurn.Up:
  16.          path.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) -1, this.Height, this.Height), 181.0f, -91.0f);
  17.          break;
  18.      case PipeTurn.Down:
  19.          path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
  20.          break;
  21.      default:
  22.          path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
  23.          break;
  24. }
复制代码

  • 关键理解:绘制的椭圆、线(Rectangle)理解了就好画了
    path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
    path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
  • 可以流动的关键要素
  1.      //流动条流动速度(刷新速度)
  2.      this.myTimer = new Timer();
  3.      myTimer.Interval = 50;
  4.      this.myTimer.Tick += MyTimer_Tick; ;
  5. }
  6. #region 定时循环
  7. private void MyTimer_Tick(object sender, EventArgs e)
  8. {
  9.      this.startOffset = this.startOffset - this.moveSpeed;
  10.      if (this.startOffset > this.flowLength + this.flowLengthGap || this.startOffset < (this.flowLength + this.flowLengthGap) * (-1))
  11.      { this.startOffset = 0; }
  12.      this.Invalidate();
  13. }
  14. #endregion
复制代码
1.定义属性


  • 管道的(两端转向、样式、边沿颜色、中间颜色、激活)
  • 流动条的(速度、长度、宽度、间隙、颜色)
  1. //属性示例:按照示例添加以上各种属性
  2. private float moveSpeed = 0.3f;
  3. [Browsable(true)]
  4. [Category("布局_G")]
  5. [Description("流动条速度,负数为反向")]  //属性说明
  6. public float MoveSpeed
  7. {
  8.     get { return moveSpeed; }
  9.     set
  10.     {
  11.         this.moveSpeed = value;
  12.         this.Invalidate();  //重绘
  13.     }
  14. }
复制代码
2.画布重绘
  1. 【管道分为左、中、右三部分。先画管道(矩形):左、中、右;再画流动条(虚线):左、中、右】
  2. //矩形画刷
  3. LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height), pipeColorEdge, pipeColorEdge);
  4. linearGradientBrush.InterpolationColors = colorBlend;
  5. //绘制左部分
  6. switch (this.pipeTurnLeft)
  7. {
  8.     case PipeTurn.Up:
  9.         this.PaintEllipse(g, colorBlend, p, new Rectangle(0, this.Height * (-1)-1, this.Height * 2, this.Height * 2), 90.0f, 90.0f);
  10.         break;
  11.     case PipeTurn.Down:
  12.         this.PaintEllipse(g, colorBlend, p, new Rectangle(0, 0, this.Height * 2, this.Height * 2), 180.0f, 90.0f);
  13.         break;
  14.     default:
  15.         this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(-1, 0, this.Height+1, this.Height));
  16.         break;
  17. }
  18. //绘制右部分
  19. switch (this.pipeTurnRight)
  20. {
  21.     case PipeTurn.Up:
  22.         this.PaintEllipse(g, colorBlend, p, new Rectangle(this.Width - this.Height * 2, this.Height * (-1)-1, this.Height * 2, this.Height * 2), 0.0f, 90.0f);
  23.         break;
  24.     case PipeTurn.Down:
  25.         this.PaintEllipse(g, colorBlend, p, new Rectangle(this.Width - this.Height * 2, 0, this.Height * 2, this.Height * 2), 270.0f, 90.0f);
  26.         break;
  27.     default:
  28.         this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(this.Width - this.Height, 0, this.Height, this.Height));
  29.         break;
  30. }
  31. //绘制中间
  32. if (this.Width > this.Height * 2)
  33. {
  34.     this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(this.Height - 1, 0, this.Width - this.Height * 2 + 2, this.Height));
  35. }
复制代码
  1. //流动条路径
  2. GraphicsPath path = new GraphicsPath();
  3. //虚线路径—左边
  4. switch (this.pipeTurnLeft)
  5. {
  6.     case PipeTurn.Up:
  7.         path.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) -1, this.Height, this.Height), 181.0f, -91.0f);
  8.         break;
  9.     case PipeTurn.Down:
  10.         path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
  11.         break;
  12.     default:
  13.         path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
  14.         break;
  15. }
  16. //虚线路径—中间
  17. if (this.Width > this.Height * 2)
  18. {
  19.     path.AddLine(this.Height, this.Height / 2, this.Width - this.Height -1, this.Height / 2);
  20. }
  21. //虚线路径—右边
  22. switch (this.pipeTurnRight)
  23. {
  24.     case PipeTurn.Up:
  25.         path.AddArc(new Rectangle(this.Width - 1 - this.Height * 3 / 2, -this.Height / 2-1 , this.Height, this.Height), 88f, -91.0f);
  26.         break;
  27.     case PipeTurn.Down:
  28.         path.AddArc(new Rectangle(this.Width - 1 - this.Height * 3 / 2, this.Height / 2, this.Height, this.Height), 270.0f, 90.0f);
  29.         break;
  30.     default:
  31.         path.AddLine(this.Width - this.Height, this.Height / 2, this.Width , this.Height / 2);
  32.         break;
  33. }
  34. //画虚线,关键用笔和路径来
  35. Pen pen = new Pen(this.flowColor, this.flowWidth);
  36. pen.DashStyle = DashStyle.Custom;
  37. pen.DashPattern = new float[]
  38. {
  39.     flowLength,flowLengthGap
  40. };
  41. pen.DashOffset = this.startOffset;
  42. g.DrawPath(pen, path);
复制代码
格式都是一样的,掌握关键代码,肝就对了。
End


来源:https://www.cnblogs.com/guoenshuo/p/18391637
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具