C#中自定义方向盘控件

因项目要求需要有方向盘的绘制,查了好多,决定自己画一个,虽然样式一般,但基本实现功能

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Diagnostics;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 
 11 namespace XXX //自己的项目名称
 12 {
 13     public partial class MyJoystick : Control
 14     {
 15         private float radius; 
 16         private PointF center;
 17         private Color frameColor = Color.FromArgb(18, 150, 219);
 18         private SolidBrush blackBrush = new SolidBrush(Color.FromArgb(18, 150, 219));
 19         private SolidBrush circleColor = new SolidBrush(Color.FromArgb(20, 20, 20));
 20         private float angle = 0;
 21 
 22 
 23         private Pen penFrame = null;  //边框画笔
 24 
 25         /// <summary>
 26         /// 角度值
 27         /// </summary>
 28         [Description("方向盘转动角度"), Category("自定义")]
 29         public float Angle
 30         {
 31             get { return this.angle; }
 32             set
 33             {            
 34                 this.angle = value;
 35                 this.Invalidate();
 36             }
 37         }
 38 
 39         /// <summary>
 40         /// 边框颜色
 41         /// </summary>
 42         [Description("方向盘边框颜色"), Category("自定义")]
 43         public Color FrameColor
 44         {
 45             get { return this.frameColor; }
 46             set
 47             {
 48                 this.frameColor = value;
 49                 this.penFrame.Color = value;
 50                 this.Invalidate();
 51             }
 52         }
 53 
 54 
 55         //解决控件批量更新时带来的闪烁
 56         protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }
 57 
 58 
 59         public MyJoystick()
 60         {
 61             InitializeComponent();
 62             //初始化变量
 63             this.penFrame = new Pen(this.frameColor, 6);
 64             this.radius = this.Width/2;
 65 
 66         }
 67 
 68 
 69         protected override void OnPaint(PaintEventArgs e)
 70         {
 71             DrawJoystick(e.Graphics);
 72         }
 73 
 74         private void DrawJoystick(Graphics g)
 75         {
 76             if (this.Width < 50 || this.Height < 50)
 77             {
 78                 return;
 79             }
 80 
 81 
 82             //双缓冲
 83             //在内存中建立一块“虚拟画布”
 84             Bitmap bmp = new Bitmap(this.Width, this.Height);
 85             //获取这块内存画布的Graphics引用
 86             g = Graphics.FromImage(bmp);
 87 
 88             //在这块内存画布上绘图
 89             g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 90             g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 91             //g.Clear(this.BackColor);
 92 
 93             //圆的大小
 94             int size = Math.Min(this.Width, this.Height);//圆的大小
 95             center = new PointF(size / 2, size / 2);
 96 
 97             //draw frame                      
 98             int sizeOffset =6;//距离最外侧的偏移量
 99             Rectangle rectangle = new Rectangle(this.Width / 2 - size / 2 + sizeOffset, this.Height / 2 - size / 2 + sizeOffset, size - (sizeOffset * 2), size - (sizeOffset * 2));//计算圆的范围
100             g.DrawArc(this.penFrame, rectangle, 0, 360);//绘制外环
101 
102 
103             //draw direction
104             int nLine1 = size / 2 - sizeOffset;
105             
106             float nCenterLineX = center.X;  //中心点X
107             float nCenterLineY = center.Y;  //中心点Y
108 
109             float x_start = nCenterLineX + (float)(nLine1) * (float)Math.Cos(Math.PI / 180 * angle);
110             float y_start = nCenterLineY + (float)(nLine1) * (float)Math.Sin(Math.PI / 180 * angle);
111 
112             PointF p1 = new PointF(x_start, y_start);
113             PointF p2 = new PointF((2 * nCenterLineX - p1.X), (2 * (nCenterLineY) - p1.Y));
114 
115             Pen mRed = new Pen(frameColor, 10);
116             g.DrawLine(mRed, p1, p2);
117 
118             int nLine2 = size / 3;     //指针底边直径
119             int nLineC = -size / 2;    //指针底边距中心Y轴的距离
120 
121 
122             float nCenterLineXX = (float)((center.X) - (nLine1) * Math.Sin(Math.PI / 180 * angle)); //起点指针顶点X
123             float nCenterLineYY = (float)((center.Y) + (nLine1) * Math.Cos(Math.PI / 180 * angle)); //起点指针顶点Y
124 
125 
126             PointF p3 = new PointF(nCenterLineXX, nCenterLineYY);//起点指针顶点
127             float x_start4 = (float)((nCenterLineX) - (nLine2 / 2) * Math.Cos(Math.PI / 180 * (-angle)));
128             float y_start4 = (float)((nCenterLineY) + (nLine2 / 2) * Math.Sin(Math.PI / 180 * (-angle)));
129 
130 
131             PointF p4 = new PointF(x_start4, y_start4);
132             float x_end4 = (float)((2 * nCenterLineX - x_start4));
133             float y_end4 = (float)((2 * (nCenterLineY) - y_start4));
134 
135             PointF p5 = new PointF(x_end4, y_end4);
136 
137             g.DrawLine(mRed, p4, p5);
138             g.DrawLine(mRed, p3, p5);
139             g.DrawLine(mRed, p3, p4);
140             PointF[] pointss = { p3, p4, p5 };
141 
142             g.FillPolygon(blackBrush, pointss);//填充区域
143             g.FillPie(circleColor, center.X - 5, center.Y - 5, 10, 10, 0, 360);//中心圆   
144 
145             //将内存画布画到窗口中
146             this.CreateGraphics().DrawImage(bmp, 0, 0);
147 
148             g.Dispose();
149             bmp.Dispose();
150         }
151 
152     }
153 }

在自己的项目中点击右键,选择添加 -> 选择新建项 -> 选择组件类,定义自己的控件名,然后复制本代码就可以了。

 然后点击生成解决方案后,就可以在工具内找到自己定义的控件了

 制作效果如下:

 

赋值的话,直接用控件名.Angle = value;就可以了

注意:此自定义控件有一个小bug,拖拽出来的控件得为正方形才可以,以后有机会再继续改进

 

 

转载需要标注转载地址哦~~~

 

posted @ 2020-04-10 10:08  洛水卿卿  阅读(578)  评论(0编辑  收藏  举报