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,拖拽出来的控件得为正方形才可以,以后有机会再继续改进
转载需要标注转载地址哦~~~