C#控件开发4—仪表盘

news2025/1/5 8:15:50

目录

  • 思路(GDI绘图)
  • 1.定义属性
  • 2.绘制图形
  • 3.最后生成(自定义各种监控值显示)
  • End

如何让温度、湿度、压力等有量程的监控值如仪表盘(DashBoard)一样显示?

思路(GDI绘图)

  • 定义属性:(仪表盘的半径、颜色、间隙;刻度圆的半径、颜色、字体;指针的颜色、占比;文本的字体、占比;)
  • 绘制图形:(半圆、刻度、指针、中心、文本)

1.定义属性

  • 将以上属性挨个敲完
        private Color colorCircle1 = Color.FromArgb(33, 80, 33);
        [Browsable(true)]
        [Category("布局_G")]
        [Description("外环颜色1")]
        public Color ColorCircle1
        {
            get { return colorCircle1; }
            set { colorCircle1 = value; this.Invalidate(); }
        }

        private Color colorCircle2 = Color.FromArgb(22, 128, 22);
        [Browsable(true)]
        [Category("布局_G")]
        [Description("外环颜色2")]
        public Color ColorCircle2
        {
            get { return colorCircle2; }
            set { colorCircle2 = value; this.Invalidate(); }
        }

        private Color colorCircle3 = Color.FromArgb(20, 181, 20);
        [Browsable(true)]
        [Category("布局_G")]
        [Description("外环颜色3")]
        public Color ColorCircle3
        {
            get { return colorCircle3; }
            set { colorCircle3 = value; this.Invalidate(); }
        }

        private Color pointColor = Color.Green;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("指针颜色")]
        public Color PointColor
        {
            get { return pointColor; }
            set { pointColor = value; this.Invalidate(); }
        }

        private Color scaleColor = Color.Black;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("刻度颜色")]
        public Color ScaleColor
        {
            get { return scaleColor; }
            set { scaleColor = value; this.Invalidate(); }
        }

        private float scaleProportion = 0.8f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("刻度圆占外圆的比例0-1:越大越紧挨")]
        public float ScaleProportion
        {
            get { return scaleProportion; }
            set
            {
                if (value > 1.0f || value < 0.0f) return;
                scaleProportion = value; this.Invalidate();
            }
        }

        private Font scaleFont = new Font(new FontFamily("微软雅黑"), 10.0f);
        [Browsable(true)]
        [Category("布局_G")]
        [Description("字体格式")]
        public Font ScaleFont
        {
            get { return scaleFont; }
            set
            {
                if (value != null)
                {
                    scaleFont = value;
                    this.Invalidate();
                }
            }
        }

        private string textPrefix = "实际温度:";
        [Browsable(true)]  //说明:文本关闭
        [Category("布局_G")]
        [Description("文本前缀")]
        public string TextPrefix
        {
            get { return textPrefix; }
            set { textPrefix = value; this.Invalidate(); }
        }

        private string textUnit = "℃";
        [Browsable(true)]  //说明:文本关闭
        [Category("布局_G")]
        [Description("文本单位")]
        public string TextUnit
        {
            get { return textUnit; }
            set { textUnit = value; this.Invalidate(); }
        }

        private Font textFont = new Font("Segoe UI", 10.5f);
        [Browsable(true)]
        [Category("布局_G")]
        [Description("字体格式")]
        public Font TextFont
        {
            get { return textFont; }
            set
            {
                if (value != null)
                {
                    textFont = value;
                    this.Invalidate();
                }
            }
        }

        private Color textColor = Color.Black;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("指针颜色")]
        public Color TextColor
        {
            get { return textColor; }
            set { textColor = value; this.Invalidate(); }
        }

        private float textProportion = 0.88f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("文本显示高度占比0-1;越小越靠上")]
        public float TextProportion
        {
            get { return textProportion; }
            set
            {
                if (value > 1.0f || value < 0.0f) return;
                textProportion = value; this.Invalidate();
            }
        }

        private bool textShow = true;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("是否显示文本")]
        public bool TextShow
        {
            get { return textShow; }

            set
            {
                textShow = value; this.Invalidate();
            }
        }

        private float currentValue = 100.0f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("实时值显示")]
        public float CurrentValue
        {
            get { return currentValue; }

            set
            {
                if (value < 0.0f || value > range) return;
                currentValue = value; this.Invalidate();
            }
        }

        private int outThickness = 5;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("外环画笔的宽度")]
        public int OutThickness
        {
            get { return outThickness; }

            set
            {
                if (value <= 0) return;
                outThickness = value; this.Invalidate();
            }
        }

        private float range = 180.0f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("量程")]
        public float Range
        {
            get { return range; }

            set
            {
                if (value < 0.0f) return;
                range = value; this.Invalidate();
            }
        }

        private float centerRadius = 6.0f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("中心半径")]
        public float CenterRadius
        {
            get { return centerRadius; }

            set
            {
                if (value <= 0.0f) return;
                centerRadius = value; this.Invalidate();
            }
        }

        private float gapAngle = 2.0f;
        [Browsable(true)]
        [Category("布局_G")]
        [Description("间隙角度")]
        public float GapAngle
        {
            get { return gapAngle; }

            set
            {
                if (value <= 0.0f) return;
                gapAngle = value; this.Invalidate();
            }
        }

        #endregion 

2.绘制图形

  • 定义画布、笔
  • 画布质量
  • 画外环-定义角度、坐标、宽度、高度
  • 画内圆
  • 画指针
  • 文本标签
private Graphics g;    //画布
private Pen p;         //笔-绘制线条、曲线
private SolidBrush sb; //笔(填充)-填充矩形、路径
private int width;
private int height;
 #region 重绘【画外圆、画刻度、画指针、画中心、画文本】
 protected override void OnPaint(PaintEventArgs e)
 {
     base.OnPaint(e);

     //画布质量
     g = e.Graphics;
     g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
     g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
     this.width = this.Width;
     this.height = this.Height;

     //特殊情况处理
     if (this.width <= 20 || this.height <= 20) return;
     if (this.height < this.width * 0.5f) return;

     // 画外环-定义角度、坐标、宽度、高度
     float angle = (180.0f - gapAngle * 2) / 3;
     RectangleF rec = new RectangleF(10, 10, this.width - 20, this.width - 20);

     //第一个圆弧
     p = new Pen(colorCircle3, outThickness);
     g.DrawArc(p, rec, -180.0f, angle);

     //第二个圆弧
     p = new Pen(colorCircle2, outThickness);
     g.DrawArc(p, rec, -180.0f + angle + gapAngle, angle);

     //第三个圆弧
     p = new Pen(colorCircle1, outThickness);
     g.DrawArc(p, rec, -180.0f + angle * 2.0f + gapAngle + 2.0f, angle);

     //画刻度
     g.TranslateTransform(this.width * 0.5f, this.width * 0.5f);

     for (int i = 0; i < 4; i++)
     {
         float actualAngle = -180.0f + 60.0f * i;
         double x1 = Math.Cos(actualAngle * Math.PI / 180);
         double y1 = Math.Sin(actualAngle * Math.PI / 180);
         float x = Convert.ToSingle(this.width * scaleProportion * 0.5f * x1);
         float y = Convert.ToSingle(this.width * scaleProportion * 0.5f * y1);

         StringFormat sf = new StringFormat();

         if (i > 1)
         {
             x = x - 60;
             sf.Alignment = StringAlignment.Far;
         }
         else
         {
             sf.Alignment = StringAlignment.Near;
         }

         //刻度的坐标,宽,高
         rec = new RectangleF(x, y, 60, 20);
         sb = new SolidBrush(scaleColor);

         if (range % 6 == 0)
         {
             g.DrawString((range / 3 * i).ToString(), scaleFont, sb, rec, sf);
         }
         else
         {
             g.DrawString((range / 3 * i).ToString("f1"), scaleFont, sb, rec, sf);
         }
     }

     //画内圆
     g.FillEllipse(new SolidBrush(pointColor), new RectangleF(-centerRadius, -centerRadius, centerRadius * 2.0f, centerRadius * 2.0f));

     //画指针
     p = new Pen(pointColor, 3.0f);  //定义指针颜色、宽度
     float sweepAngle = currentValue / range * 180.0f; //划过的角度
     float z = this.width * 0.5f * scaleProportion - outThickness * 0.5f - 20.0f;  //指针长度
     g.RotateTransform(90.0f); //默认开始角度
     g.RotateTransform(sweepAngle);

     //画线
     g.DrawLine(p, new PointF(0, 0), new PointF(0, z));

     //文本标签
     if (textShow)
     {
         g.RotateTransform(-sweepAngle);
         g.RotateTransform(-90.0f);
         StringFormat sf = new StringFormat();
         sf.Alignment = StringAlignment.Center;
         rec = new RectangleF(this.width * (-0.5f), this.height * textProportion - 0.5f * this.width, this.width, this.height * (1.0f - this.scaleProportion));
         //string val = TextPrefix + currentValue.ToString() + "" + textUnit + "(" + (currentValue / range * 100.0f).ToString("f0") + "%" + ")";
         string val = TextPrefix + currentValue.ToString() + "" + textUnit ;

         //文本
         g.DrawString(val, textFont, new SolidBrush(textColor), rec, sf);

     }
 }


 #endregion

3.最后生成(自定义各种监控值显示)


End

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2269854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

提升口语发音水平,中英文发音评测系统实现

在全球化的浪潮中&#xff0c;语言不再是障碍&#xff0c;而是连接世界的桥梁。掌握一门流利的英语&#xff0c;意味着打开了通往世界的大门。但是&#xff0c;如何确保你的英语口语如同母语者一样自然流畅&#xff1f;这正是我们存在的意义。 我们的中英文口语发音评测服务&a…

JVM对象创建过程

1 类加载检查 jvm通过new指令开始创建对象jvm执行new指令时&#xff0c;首先通过指令参数从常量池中取到需要创建的类名检查该类是否被加载&#xff0c;解析&#xff0c;和初始化过如果没有&#xff0c;则执行类的加载过程new指令对应到java语言具体的操作为 new 关键字创建对象…

什么是Sight Words(信号词)

&#x1f9e1;什么是Sight Words&#xff08;信号词&#xff09; 简单来说&#xff0c;Sight Words就是我们在日常英语中常用的一些基本词汇。可以把它想象成是学练英语的“基础词汇”&#xff0c;这些词在各种考试中经常出现&#xff0c;也是在生活中必不可少的。 &#x1f…

秒鲨后端之MyBatis【3】自定义映射resultMap、动态SQL、MyBatis的缓存、MyBatis的逆向工程、分页插件(30000字)

这里我分享一下尚硅谷的pdf100页笔记和代码&#xff0c;大家可以参考学习。 笔记&#xff1a; 通过网盘分享的文件&#xff1a;MyBatis.pdf 链接: https://pan.baidu.com/s/14Iu1Zs-_5vZoRjBEjmagag?pwdyjh6 提取码: yjh6 --来自百度网盘超级会员v1的分享代码&#xff1a; …

12.31【Linux】shell脚本【运行方式,修改环境变量,数组】思维导图 内附练习

1.思维导图 2练习&#xff1a; 1.尝试将下列指令放到脚本中运行 在家目录下创建目录文件dir1&#xff0c;把/etc/passwd拷贝到dir1中&#xff0c;把/etc/group拷贝到dir1中并重命名为grp.txt&#xff0c;使用tree指令&#xff0c;显示dir1目录的文件树&#xff0c;把dir1&am…

云计算学习架构篇之HTTP协议、Nginx常用模块与Nginx服务实战

一.HTTP协议讲解 1.1rsync服务重构 bash 部署服务端: 1.安装服务 [rootbackup ~]# yum -y install rsync 2.配置服务 [rootbackup ~]# vim /etc/rsyncd.conf uid rsync gid rsync port 873 fake super yes use chroot no max connections 200 timeout 600 ignore erro…

【项目】智能BI洞察引擎 测试报告

目录 一、项目背景BI介绍问题分析项目背景 二、项目功能三、功能测试1、登录测试测试用例测试结果 2、注册测试测试用例测试结果出现的bug 3、上传文件测试测试用例测试结果 4、AI生成图表测试测试用例测试结果 5、分析数据页面测试&#xff08;异步&#xff09;测试用例测试结…

权限菜单之菜单管理 SpringBoot + VUE

一、 数据表设计 新建表sys_menu 表内数据 添加实体类Menu package com.example.demo.demos.web.demo.entity;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.Ta…

【AIGC篇】AIGC 引擎:点燃创作自动化的未来之火

&#xff1a;羑悻的小杀马特.-CSDN博客 未来都是惊喜。你生来本应为高山。并非草芥。 引言&#xff1a; 在当今数字化的时代&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;正以一种前所未有的力量改变着我们的创作领域。它就像一个神秘而强大的魔法师&#xff0c;…

UnityRenderStreaming使用记录(三)

测试UnityRenderStreaming在Ubuntu24.04.1LTS上的表现 先放上运行图操作系统 Ubuntu24.04.1LTSUnity测试工程环境相关修改遇到的问题 先放上运行图 操作系统 Ubuntu24.04.1LTS 系统下载地址 https://cn.ubuntu.com/download/desktop安装UnityHub https://blog.csdn.net/AWNUXC…

从0开始的docker镜像制作-ubuntu22.04

从0开始的docker镜像制作-ubuntu22.04 一、拉取基础ubuntu22.04镜像二、进入拉取的docker镜像中&#xff0c;下载自己需要的安装包三、安装需要的系统软件四、打包现有镜像为一个新的镜像五、推送打包的镜像到私有docker服务器1.编辑docker文件&#xff0c;使其允许http传输和对…

多模态论文笔记——CogVLM和CogVLM2(副)

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型的LoRA版本——CogVLM和CogVLM2。在SD 3中使用其作为captioner基准模型的原因和优势。 文章目录 CogVLM论文背景VLMs 的任务与挑战现有方法及…

gitlab-runner的卸载与安装

如果你使用rpm方式安装gitlab-runner&#xff0c;则可以参考本教程。 卸载 停止和卸载gitlab-runner 停止 gitlab-runner stopchkconfig gitlab-runner off卸载 gitlab-runner uninstall删除rpm包 查询出rpm包名&#xff0c;根据包名删除rpm。 [rootEuler02 ~]# rpm -qa …

Nacos配置中心总结

Nacos配置中心总结 Nacos配置文件的加载顺序和优先级 加载顺序 nacos作为配置中心时&#xff0c;需要在bootstrap.yml文件中添加nacos config相关的配置&#xff0c;这样系统启动时就能先去拉取nacos server上的配置了。拉取过来后会和本地配置文件进行合并。 bootstrap.ym…

赛博周刊·2024年度工具精选(图片资源类)

1、EmojiSpark emoji表情包查找工具。 2、fluentui-emoji 微软开源的Fluent Emoji表情包。 3、开源Emoji库 一个开源的emoji库&#xff0c;目前拥有4000个emoji表情。 4、中国表情包大合集博物馆 一个专门收集中国表情包的项目&#xff0c;已收录5712张表情包&#xff0c;并…

Goland:专为Go语言设计的高效IDE

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;Goland是JetBrains公司开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Go语言设计&#xff0c;提供了高效的代码编辑、强大的调试工具和丰富的项目管理功能。其智能代码补全、强大的调试与测试支…

小程序发版后,用户使用时,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…

EasyExcel(环境搭建以及常用写入操作)

文章目录 EasyExcel环境搭建1.创建模块 easyexcel-demo2.引入依赖3.启动类创建 EasyExcel写1.最简单的写入1.模板2.方法3.结果 Write01.xlsx 2.指定字段不写入Excel1.模板2.方法3.结果 Write02.xlsx 3.指定字段写入excel1.模板2.方法3.结果 Write03.xlsx 4.按照index顺序写入ex…

典型常见的基于知识蒸馏的目标检测方法总结三

来源&#xff1a;Google学术2023-2024的顶会顶刊论文 NeurIPS 2022&#xff1a;Towards Efficient 3D Object Detection with Knowledge Distillation 为3D目标检测提出了一种知识蒸馏的Benchmark范式&#xff0c;包含feature的KD&#xff0c;Logit的cls和reg的KD&#xff0c…

通过Dockerfile来实现项目可以指定读取不同环境的yml包

通过Dockerfile来实现项目可以指定读取不同环境的yml包 1. 挂载目录2. DockerFile3. 运行脚本deploy.sh4. 运行查看日志进入容器 5. 接口测试修改application-dev.yml 6. 优化Dockerfile7. 部分参数解释8. 优化不同环境下的日志也不同调整 Dockerfile修改部署脚本 deploy.sh重新…