当前位置: 首页 > news >正文

WinForm仪表盘

1.创建一个DashboardControl类

DashboardControl类的代码如下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Dashboard
{public class DashboardControl : Control{#region 属性和字段// 仪表盘设置private float _minValue = 0;private float _maxValue = 100;private float _currentValue = 0;private float _warningValue = 80;private float _dangerValue = 90;// 外观设置 - 修改默认背景色private Color _backgroundColor = Color.Black;  // 改为不透明颜色private Color _dialColor = Color.FromArgb(30, 30, 30);private Color _scaleColor = Color.White;private Color _pointerColor = Color.Red;private Color _warningColor = Color.Orange;private Color _dangerColor = Color.Red;private Color _valueColor = Color.White;private Color _titleColor = Color.LightGray;// 字体private Font _valueFont;private Font _titleFont;private Font _scaleFont;// 文本private string _title = "仪表盘";private string _unit = "单位";// 尺寸比例private float _dialThickness = 0.1f;private float _pointerLength = 0.7f;private float _pointerWidth = 0.02f;#endregion#region 属性公开接口public float MinValue{get { return _minValue; }set { _minValue = value; Invalidate(); }}public float MaxValue{get { return _maxValue; }set { _maxValue = value; Invalidate(); }}public float CurrentValue{get { return _currentValue; }set{_currentValue = Math.Max(_minValue, Math.Min(_maxValue, value));Invalidate();}}public float WarningValue{get { return _warningValue; }set { _warningValue = value; Invalidate(); }}public float DangerValue{get { return _dangerValue; }set { _dangerValue = value; Invalidate(); }}public Color BackgroundColor{get { return _backgroundColor; }set { _backgroundColor = value; Invalidate(); }}public Color DialColor{get { return _dialColor; }set { _dialColor = value; Invalidate(); }}public Color PointerColor{get { return _pointerColor; }set { _pointerColor = value; Invalidate(); }}public Color ScaleColor{get { return _scaleColor; }set { _scaleColor = value; Invalidate(); }}public string Title{get { return _title; }set { _title = value; Invalidate(); }}public string Unit{get { return _unit; }set { _unit = value; Invalidate(); }}public Color WarningColor{get { return _warningColor; }set { _warningColor = value; Invalidate(); }}public Color DangerColor{get { return _dangerColor; }set { _dangerColor = value; Invalidate(); }}#endregion#region 构造函数public DashboardControl(){// 初始化字体_valueFont = new Font("Arial", 16, FontStyle.Bold);_titleFont = new Font("Arial", 12);_scaleFont = new Font("Arial", 8);this.DoubleBuffered = true;// 修复:使用不透明的背景色this.BackColor = Color.Black;  // 改为不透明颜色this.Size = new Size(200, 200);// 设置控件样式,确保正确绘制SetStyle(ControlStyles.AllPaintingInWmPaint |ControlStyles.UserPaint |ControlStyles.DoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.Opaque, true);  // 添加 Opaque 样式}#endregion#region 绘图方法protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.AntiAlias;g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;// 先清除背景using (SolidBrush backgroundBrush = new SolidBrush(_backgroundColor)){g.FillRectangle(backgroundBrush, this.ClientRectangle);}// 计算仪表盘尺寸和位置int size = Math.Min(Width, Height) - 20;if (size <= 0) return;  // 添加安全检查int x = (Width - size) / 2;int y = (Height - size) / 2;RectangleF dialRect = new RectangleF(x, y, size, size);// 绘制表盘DrawDial(g, dialRect);// 绘制刻度DrawScales(g, dialRect);// 绘制指针DrawPointer(g, dialRect);// 绘制数值和标题DrawText(g, dialRect);}private void DrawDial(Graphics g, RectangleF dialRect){// 绘制表盘底色using (SolidBrush brush = new SolidBrush(_dialColor)){g.FillEllipse(brush, dialRect);}// 绘制渐变效果using (GraphicsPath path = new GraphicsPath()){path.AddEllipse(dialRect);using (PathGradientBrush pgb = new PathGradientBrush(path)){pgb.CenterPoint = new PointF(dialRect.X + dialRect.Width * 0.3f,dialRect.Y + dialRect.Height * 0.3f);pgb.CenterColor = Color.FromArgb(100, 255, 255, 255);pgb.SurroundColors = new Color[] { Color.Transparent };g.FillEllipse(pgb, dialRect);}}// 绘制刻度区域(彩色圆弧)DrawColorZones(g, dialRect);// 绘制外边框using (Pen borderPen = new Pen(Color.FromArgb(100, 255, 255, 255), 2f)){g.DrawEllipse(borderPen, dialRect);}}private void DrawColorZones(Graphics g, RectangleF dialRect){float startAngle = 135;float sweepAngle = 270;// 检查除零错误if (_maxValue - _minValue <= 0) return;// 正常区域(绿色)float normalSweep = (_warningValue - _minValue) / (_maxValue - _minValue) * sweepAngle;if (normalSweep > 0)DrawZone(g, dialRect, startAngle, normalSweep, Color.Green);// 警告区域(橙色)float warningSweep = (_dangerValue - _warningValue) / (_maxValue - _minValue) * sweepAngle;if (warningSweep > 0)DrawZone(g, dialRect, startAngle + normalSweep, warningSweep, _warningColor);// 危险区域(红色)float dangerSweep = (_maxValue - _dangerValue) / (_maxValue - _minValue) * sweepAngle;if (dangerSweep > 0)DrawZone(g, dialRect, startAngle + normalSweep + warningSweep, dangerSweep, _dangerColor);}private void DrawZone(Graphics g, RectangleF dialRect, float startAngle, float sweepAngle, Color color){if (sweepAngle <= 0) return;float penWidth = dialRect.Width * _dialThickness;if (penWidth <= 0) return;RectangleF zoneRect = new RectangleF(dialRect.X + penWidth / 2,dialRect.Y + penWidth / 2,dialRect.Width - penWidth,dialRect.Height - penWidth);using (Pen zonePen = new Pen(color, penWidth)){zonePen.StartCap = LineCap.Round;zonePen.EndCap = LineCap.Round;g.DrawArc(zonePen, zoneRect, startAngle, sweepAngle);}}private void DrawScales(Graphics g, RectangleF dialRect){float startAngle = 135;float sweepAngle = 270;int majorDivisions = 10;int minorDivisions = 5;float penWidth = dialRect.Width * 0.01f;float majorTickLength = dialRect.Width * 0.05f;float minorTickLength = dialRect.Width * 0.025f;using (Pen majorPen = new Pen(_scaleColor, penWidth * 2))using (Pen minorPen = new Pen(_scaleColor, penWidth))using (SolidBrush textBrush = new SolidBrush(_scaleColor)){PointF center = new PointF(dialRect.X + dialRect.Width / 2, dialRect.Y + dialRect.Height / 2);float radius = dialRect.Width / 2;for (int i = 0; i <= majorDivisions; i++){float angle = startAngle + (sweepAngle / majorDivisions) * i;float radian = angle * (float)Math.PI / 180;// 主刻度PointF outerPoint = new PointF(center.X + radius * (float)Math.Cos(radian),center.Y + radius * (float)Math.Sin(radian));PointF innerPoint = new PointF(center.X + (radius - majorTickLength) * (float)Math.Cos(radian),center.Y + (radius - majorTickLength) * (float)Math.Sin(radian));g.DrawLine(majorPen, outerPoint, innerPoint);// 主刻度数值float value = _minValue + (_maxValue - _minValue) * i / majorDivisions;string text = value.ToString("F0");SizeF textSize = g.MeasureString(text, _scaleFont);PointF textPoint = new PointF(center.X + (radius - majorTickLength - textSize.Height) * (float)Math.Cos(radian) - textSize.Width / 2,center.Y + (radius - majorTickLength - textSize.Height) * (float)Math.Sin(radian) - textSize.Height / 2);g.DrawString(text, _scaleFont, textBrush, textPoint);// 次刻度if (i < majorDivisions){for (int j = 1; j < minorDivisions; j++){float minorAngle = angle + (sweepAngle / majorDivisions / minorDivisions) * j;float minorRadian = minorAngle * (float)Math.PI / 180;PointF minorOuter = new PointF(center.X + radius * (float)Math.Cos(minorRadian),center.Y + radius * (float)Math.Sin(minorRadian));PointF minorInner = new PointF(center.X + (radius - minorTickLength) * (float)Math.Cos(minorRadian),center.Y + (radius - minorTickLength) * (float)Math.Sin(minorRadian));g.DrawLine(minorPen, minorOuter, minorInner);}}}}}private void DrawPointer(Graphics g, RectangleF dialRect){PointF center = new PointF(dialRect.X + dialRect.Width / 2, dialRect.Y + dialRect.Height / 2);float radius = dialRect.Width / 2;// 计算指针角度float normalizedValue = (_currentValue - _minValue) / (_maxValue - _minValue);float angle = 135 + normalizedValue * 270;float radian = angle * (float)Math.PI / 180;// 指针长度float pointerLength = radius * _pointerLength;float pointerWidth = radius * _pointerWidth;// 指针端点PointF tipPoint = new PointF(center.X + pointerLength * (float)Math.Cos(radian),center.Y + pointerLength * (float)Math.Sin(radian));// 指针两侧点float perpendicularRadian = radian + (float)Math.PI / 2;PointF side1 = new PointF(center.X + pointerWidth * (float)Math.Cos(perpendicularRadian),center.Y + pointerWidth * (float)Math.Sin(perpendicularRadian));PointF side2 = new PointF(center.X - pointerWidth * (float)Math.Cos(perpendicularRadian),center.Y - pointerWidth * (float)Math.Sin(perpendicularRadian));// 绘制指针using (GraphicsPath path = new GraphicsPath()){path.AddLine(side1, tipPoint);path.AddLine(tipPoint, side2);path.CloseFigure();using (SolidBrush brush = new SolidBrush(_pointerColor)){g.FillPath(brush, path);}// 指针边框using (Pen borderPen = new Pen(Color.DarkRed, pointerWidth * 0.3f)){g.DrawPath(borderPen, path);}}// 绘制中心点float centerSize = pointerWidth * 2;using (SolidBrush centerBrush = new SolidBrush(Color.Silver)){g.FillEllipse(centerBrush,center.X - centerSize / 2,center.Y - centerSize / 2,centerSize, centerSize);}using (Pen centerPen = new Pen(Color.Gray, pointerWidth * 0.2f)){g.DrawEllipse(centerPen,center.X - centerSize / 2,center.Y - centerSize / 2,centerSize, centerSize);}}private void DrawText(Graphics g, RectangleF dialRect){PointF center = new PointF(dialRect.X + dialRect.Width / 2, dialRect.Y + dialRect.Height / 2);using (SolidBrush valueBrush = new SolidBrush(_valueColor))using (SolidBrush titleBrush = new SolidBrush(_titleColor))using (StringFormat format = new StringFormat()){format.Alignment = StringAlignment.Center;format.LineAlignment = StringAlignment.Center;// 绘制当前值string valueText = string.Format("{0:F1} {1}", _currentValue, _unit);RectangleF valueRect = new RectangleF(center.X - dialRect.Width / 2,center.Y + dialRect.Height * 0.1f,dialRect.Width,_valueFont.Height * 1.5f);g.DrawString(valueText, _valueFont, valueBrush, valueRect, format);// 绘制标题RectangleF titleRect = new RectangleF(center.X - dialRect.Width / 2,center.Y + dialRect.Height * 0.3f,dialRect.Width,_titleFont.Height * 1.2f);g.DrawString(_title, _titleFont, titleBrush, titleRect, format);}}#endregionprotected override void OnResize(EventArgs e){base.OnResize(e);Invalidate();}protected override void Dispose(bool disposing){if (disposing){if (_valueFont != null) _valueFont.Dispose();if (_titleFont != null) _titleFont.Dispose();if (_scaleFont != null) _scaleFont.Dispose();}base.Dispose(disposing);}}}

然后在WinForm的工具箱的自定义控件就可以直接拉取

http://www.dtcms.com/a/428577.html

相关文章:

  • 做网站找酷万体育器材网站模板
  • 如何免费做公司网站wordpress模板带后台
  • Linux日志查看常用命令
  • 泰安整站优化wordpress头部空白
  • 考研408之栈与队列学习
  • 软考-系统架构设计师 软件架构概念详细讲解
  • 都匀网站建设住建部注册中心官网
  • Problem: lab-week4- exercise02 Quick sort
  • 营销型网站策划怎么做中国公司查询网站
  • 通信领域常见基本概念与术语
  • Trae CN配置Maven环境
  • 门户网站改版计算机网页设计就业方向
  • 无锡网站设计哪家公司好长春火车站照片
  • 石油钻井为何离不开抗高温抗冲击的石英加速度计?
  • matlab | 基于MATLAB的抽烟识别系统设计:技术框架与实现路径
  • 时间序列 + SHAP/LIME,实现可解释性再突破!
  • 宿迁建设企业网站淘宝接单做网站
  • ACM Comput. Surv.投稿
  • 网站产品分类设计百度做销售网站多少钱
  • 延安免费做网站公司温州网站推广外包
  • 产业资源+金融赋能!沃飞长空与金石租赁开启深度合作
  • 大余网站app的开发需要多少钱
  • 做网站要到通信管理局备案专业俄文网站建设
  • 苏州电信网站备案泉州市亿民建设发展有限公司网站
  • 新天力:为食品安全而生的食品容器专家
  • 程序员创业注意事项
  • 沃尔沃XC70正式上市,积极布局混插市场的沃尔沃未来何在?
  • 使用lombok的sl4j注解,报错java: 找不到符号 符号: 变量 log
  • 廊坊网站建设搭建wordpress页面管理
  • 26.渗透-.Linux基础命令(十八)-Linux系统状态管理(安全加固-查找空密码账号)