C# GDI+数码管数字控件
调用方法
int zhi = 15;private void button1_Click(object sender, EventArgs e){if (++zhi > 19){zhi = 0;}lcdDisplayControl1.DisplayText = zhi.ToString();}
运行效果

控件代码
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp1
{public class LcdDisplayControl : Control{private string _displayText = "0";private Color _digitColor = Color.LightGreen;private Color _backgroundColor = Color.Black;private const float SEGMENT_WIDTH_RATIO = 0.15f; //每个发光段的宽度比例private const float DIGIT_HEIGHT_RATIO = 0.8f; //数字显示区域的高度比例private const float SEGMENT_GAP_RATIO = 0.05f; //段之间的间隙比例private float _padding = 2f;private Color _shadowColor = Color.FromArgb(30, Color.LightGreen); // 默认投影颜色 private float _shadowOffset = 1.5f; // 默认投影偏移量 private bool _enableGlassEffect = true;private Color _glassHighlightColor = Color.FromArgb(40, Color.White);private float _glassEffectHeight = 0.4f; // 玻璃效果占控件高度的比例 private Timer _animationTimer;private double _currentValue = 0;private double _targetValue = 0;private bool _isAnimating = false;private int _animationDuration = 1000; // 默认动画持续时间(毫秒) private DateTime _animationStartTime;private string _originalFormat = "0"; // 保存显示格式 public float Padding{get => _padding;set{if (_padding != value){_padding = Math.Max(0, value);Invalidate();}}}public int AnimationDuration{get => _animationDuration;set{if (_animationDuration != value && value > 0){_animationDuration = value;}}}public bool EnableGlassEffect{get => _enableGlassEffect;set{if (_enableGlassEffect != value){_enableGlassEffect = value;Invalidate();}}}public Color GlassHighlightColor{get => _glassHighlightColor;set{if (_glassHighlightColor != value){_glassHighlightColor = value;Invalidate();}}}public Color ShadowColor{get => _shadowColor;set{if (_shadowColor != value){_shadowColor = value;Invalidate();}}}public float ShadowOffset{get => _shadowOffset;set{if (_shadowOffset != value){_shadowOffset = Math.Max(0, value); // 确保偏移量不为负数 Invalidate();}}}public LcdDisplayControl(){SetStyle(ControlStyles.DoubleBuffer |ControlStyles.AllPaintingInWmPaint |ControlStyles.UserPaint |ControlStyles.ResizeRedraw, true);ForeColor = _digitColor;EnableGlassEffect = true; // 默认启用玻璃效果 _animationTimer = new Timer();_animationTimer.Interval = 16; // 约60fps _animationTimer.Tick += AnimationTimer_Tick;}public string DisplayText{get => _displayText;set{if (_displayText != value){// 尝试解析新值 if (double.TryParse(value, out double newValue)){// 保存显示格式 _originalFormat = value.Contains(".") ?"F" + (value.Length - value.IndexOf('.') - 1) : "0";// 开始动画 StartAnimation(newValue);}else{// 如果不是数字,直接设置 _displayText = value;Invalidate();}}}}public Color DigitColor{get => _digitColor;set{if (_digitColor != value){_digitColor = value;Invalidate();}}}private void StartAnimation(double targetValue){_targetValue = targetValue;_currentValue = double.TryParse(_displayText, out double currentValue) ?currentValue : 0;if (_currentValue == _targetValue)return;_animationStartTime = DateTime.Now;_isAnimating = true;_animationTimer.Start();}private void AnimationTimer_Tick(object sender, EventArgs e){var elapsed = (DateTime.Now - _animationStartTime).TotalMilliseconds;var progress = Math.Min(elapsed / _animationDuration, 1.0);// 使用缓动函数使动画更自然 progress = EaseOutCubic(progress);// 计算当前值 _currentValue = _currentValue + (_targetValue - _currentValue) * progress;// 更新显示 _displayText = _currentValue.ToString(_originalFormat);Invalidate();// 检查动画是否完成 if (progress >= 1.0){_animationTimer.Stop();_isAnimating = false;_currentValue = _targetValue;_displayText = _targetValue.ToString(_originalFormat);Invalidate();}}// 缓动函数 private double EaseOutCubic(double t){return 1 - Math.Pow(1 - t, 3);}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.HighQuality;g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.PixelOffsetMode = PixelOffsetMode.HighQuality;g.CompositingQuality = CompositingQuality.HighQuality;// 绘制背景和边框 using (var bgBrush = new SolidBrush(_backgroundColor)){g.FillRectangle(bgBrush, ClientRectangle);}// 计算实际显示区域(考虑内边距和边框) float effectivePadding = _padding;float displayAreaWidth = Width - (effectivePadding * 2);float displayAreaHeight = Height - (effectivePadding * 2);// 计算单个数字的大小 float digitWidth = displayAreaWidth / _displayText.Length;float digitHeight = displayAreaHeight * 0.8f;// 起始位置(考虑内边距和边框) float x = effectivePadding;float y = effectivePadding + (displayAreaHeight - digitHeight) / 2;// 绘制数字 for (int i = 0; i < _displayText.Length; i++){if (_displayText[i] == '.'){DrawDecimalPoint(g, x, y, digitWidth, digitHeight);x += digitWidth * 0.3f;}else{DrawDigit(g, _displayText[i], x, y, digitWidth, digitHeight);x += digitWidth;}}// 如果启用玻璃效果,绘制玻璃效果 if (_enableGlassEffect){DrawGlassEffect(g);}}// 玻璃效果绘制方法 private void DrawGlassEffect(Graphics g){float glassHeight = Height * _glassEffectHeight;// 创建渐变画笷 using (var path = new GraphicsPath()){path.AddRectangle(new RectangleF(0, 0, Width, glassHeight));// 创建渐变 using (var brush = new LinearGradientBrush(new PointF(0, 0),new PointF(0, glassHeight),Color.FromArgb(60, _glassHighlightColor),Color.FromArgb(10, _glassHighlightColor))){g.FillPath(brush, path);}// 添加微弱的边缘高光 float highlightThickness = 1.0f;using (var highlightBrush = new LinearGradientBrush(new RectangleF(0, 0, Width, highlightThickness),Color.FromArgb(100, _glassHighlightColor),Color.FromArgb(0, _glassHighlightColor),LinearGradientMode.Vertical)){g.FillRectangle(highlightBrush, 0, 0, Width, highlightThickness);}}}private void DrawDigit(Graphics g, char digit, float x, float y, float width, float height){bool[] segments = GetSegments(digit);float segmentWidth = width * SEGMENT_WIDTH_RATIO;float segmentLength = width * 0.8f;float gap = width * SEGMENT_GAP_RATIO;// 水平段 if (segments[0]) DrawHorizontalSegment(g, x + gap, y, segmentLength, segmentWidth); // 顶段 if (segments[3]) DrawHorizontalSegment(g, x + gap, y + height / 2, segmentLength, segmentWidth); // 中段 if (segments[6]) DrawHorizontalSegment(g, x + gap, y + height - segmentWidth, segmentLength, segmentWidth); // 底段 // 垂直段 if (segments[1]) DrawVerticalSegment(g, x, y + gap, segmentWidth, height / 2 - gap); // 左上 if (segments[2]) DrawVerticalSegment(g, x + segmentLength, y + gap, segmentWidth, height / 2 - gap); // 右上 if (segments[4]) DrawVerticalSegment(g, x, y + height / 2 + gap, segmentWidth, height / 2 - gap); // 左下 if (segments[5]) DrawVerticalSegment(g, x + segmentLength, y + height / 2 + gap, segmentWidth, height / 2 - gap); // 右下 }private void DrawHorizontalSegment(Graphics g, float x, float y, float length, float width){using (var path = new GraphicsPath()){// 创建水平段的路径 path.AddLine(x + width / 2, y, x + length - width / 2, y);path.AddLine(x + length, y + width / 2, x + length - width / 2, y + width);path.AddLine(x + width / 2, y + width, x, y + width / 2);path.CloseFigure();// 绘制阴影效果 using (var shadowBrush = new SolidBrush(_shadowColor)){var shadowPath = (GraphicsPath)path.Clone();var shadowMatrix = new Matrix();shadowMatrix.Translate(_shadowOffset, _shadowOffset);shadowPath.Transform(shadowMatrix);g.FillPath(shadowBrush, shadowPath);shadowPath.Dispose();}// 绘制主体 using (var brush = new SolidBrush(_digitColor)){g.FillPath(brush, path);}// 如果启用玻璃效果,添加额外的光泽 if (_enableGlassEffect){using (var glassBrush = new LinearGradientBrush(new RectangleF(x, y, length, width),Color.FromArgb(40, Color.White),Color.FromArgb(10, Color.White),LinearGradientMode.Vertical)){g.FillPath(glassBrush, path);}}// 添加发光边缘 using (var pen = new Pen(Color.FromArgb(100, _digitColor), 0.5f)){g.DrawPath(pen, path);}}}private void DrawVerticalSegment(Graphics g, float x, float y, float width, float length){using (var path = new GraphicsPath()){path.AddLine(x, y + width / 2, x + width / 2, y);path.AddLine(x + width, y + width / 2, x + width / 2, y + length);path.AddLine(x, y + length - width / 2, x, y + width / 2);path.CloseFigure();// 绘制阴影 using (var shadowBrush = new SolidBrush(_shadowColor)){var shadowPath = (GraphicsPath)path.Clone();var shadowMatrix = new Matrix();shadowMatrix.Translate(_shadowOffset, _shadowOffset);shadowPath.Transform(shadowMatrix);g.FillPath(shadowBrush, shadowPath);shadowPath.Dispose();}// 绘制主体 using (var brush = new SolidBrush(_digitColor)){g.FillPath(brush, path);}// 如果启用玻璃效果,添加额外的光泽 if (_enableGlassEffect){using (var glassBrush = new LinearGradientBrush(new RectangleF(x, y, width, length),Color.FromArgb(40, Color.White),Color.FromArgb(10, Color.White),LinearGradientMode.Vertical)){g.FillPath(glassBrush, path);}}// 添加发光边缘 using (var pen = new Pen(Color.FromArgb(100, _digitColor), 0.5f)){g.DrawPath(pen, path);}}}private void DrawDecimalPoint(Graphics g, float x, float y, float width, float height){float dotSize = width * 0.2f;// 绘制阴影效果 using (var shadowBrush = new SolidBrush(_shadowColor)){g.FillEllipse(shadowBrush,x + _shadowOffset,y + height - dotSize + _shadowOffset,dotSize,dotSize);}// 绘制主体 using (var brush = new SolidBrush(_digitColor)){g.FillEllipse(brush, x, y + height - dotSize, dotSize, dotSize);}// 添加发光边缘 using (var pen = new Pen(Color.FromArgb(100, _digitColor), 0.5f)){g.DrawEllipse(pen, x, y + height - dotSize, dotSize, dotSize);}}private bool[] GetSegments(char digit){// 7段显示的状态表 [顶, 左上, 右上, 中, 左下, 右下, 底] switch (digit){case '0': return new bool[] { true, true, true, false, true, true, true };case '1': return new bool[] { false, false, true, false, false, true, false };case '2': return new bool[] { true, false, true, true, true, false, true };case '3': return new bool[] { true, false, true, true, false, true, true };case '4': return new bool[] { false, true, true, true, false, true, false };case '5': return new bool[] { true, true, false, true, false, true, true };case '6': return new bool[] { true, true, false, true, true, true, true };case '7': return new bool[] { true, false, true, false, false, true, false };case '8': return new bool[] { true, true, true, true, true, true, true };case '9': return new bool[] { true, true, true, true, false, true, true };default: return new bool[] { false, false, false, false, false, false, false };}}protected override void Dispose(bool disposing){if (disposing){if (_animationTimer != null){_animationTimer.Stop();_animationTimer.Dispose();}}base.Dispose(disposing);}}
}
参考链接
C# GDI+ 自定义液晶数字显示控件实现
https://mp.weixin.qq.com/s?__biz=MzUxMjI3OTQzMQ==&mid=2247492775&idx=2&sn=4d9ebea27a83f5d8b126f2a12ab814ff&chksm=f898d37124d498cd3679d8eeb087628128d88d5aad24894436e18c92ac88b0c8bb87dab626d4&mpshare=1&scene=1&srcid=1227wTdlchamy68RzROrTh1n&sharer_shareinfo=91591cbc57360386ce01226fefa68fea&sharer_shareinfo_first=ced9494296615bca82d9118cef9b2a63&exportkey=n_ChQIAhIQ%2BOKdOkcv%2FxioQG8f08%2F7QBKfAgIE97dBBAEAAAAAAD1%2BOc5nK1QAAAAOpnltbLcz9gKNyK89dVj0XeVuyql%2F1aB8a7B5UUEJ50Jp43nndJjF0zdyTORUnAgO0mKKprVb6%2FtFZovUk3Zb3Rs27dOnI%2FMrKVUz6p7jURoFUhTBmK%2B%2B5%2BdUm6sLkPUwLSHmrRpDm96WBI%2F4%2BjyXSDEWceHct1KQz%2BQwZGLrrP79wUcpYKcYFrm6k22sox5Yl9Z0gwB1Hm32kegC58sCv5JlOm7deiL2YPL9DK3Jy%2BTNNHBNp9CnejYgbEjCHpPqasDEZCntntqKoqZPcR6xr7WAXm2DpBjBxqAhIfzT0BpUArzrlVnB1g4ZKHpteq1Y4p30CgfdA4fuWw9rdsT1X%2BKXHQfdfJnG&acctmode=0&pass_ticket=til6Grkg7Hy%2FLLLcFHsrar09TbMKp9qdr5Vnsoq6563Z%2FVtuuVASoekDIseEXV%2B8&wx_header=0#rd特此记录
anlog
2024年12月27日
相关文章:
C# GDI+数码管数字控件
调用方法 int zhi 15;private void button1_Click(object sender, EventArgs e){if (zhi > 19){zhi 0;}lcdDisplayControl1.DisplayText zhi.ToString();} 运行效果 控件代码 using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using …...
在交叉编译中,常见的ELF(elf)到底是什么意思?
ELF 是 Executable and Linkable Format 的缩写,中文翻译为“可执行与可链接格式”。它是一种通用的文件格式,主要用于存储可执行文件、目标文件(编译后的中间文件)、动态库(.so 文件)以及内存转储文件&…...
Unity开发AR之Vuforia-MultiTarget笔记
前言 在增强现实(AR)技术蓬勃发展的今天,越来越多的开发者开始探索如何将AR应用于各种场景中。Vuforia作为一个领先的AR开发平台,为开发者提供了强大的工具和功能,使得创建AR体验变得更加简单和直观。本文将为您介绍Vuforia的基本概念、特点,以及如何配置和使用MultiTar…...
深入解析 Oracle 的聚合函数 ROLLUP
目录 深入解析 Oracle 的聚合函数 ROLLUP一、ROLLUP 函数概述二、ROLLUP 函数语法三、ROLLUP 实例详解(一)基础分组聚合(二)引入 ROLLUP 函数(三)ROLLUP 与 NULL 值(四)多列复杂分组…...
Wend看源码-Java-集合学习(List)
摘要 本篇文章深入探讨了基于JDK 21版本的Java.util包中提供的多样化集合类型。在Java中集合共分类为三种数据结构:List、Set和Queue。本文将详细阐述这些数据类型的各自实现,并按照线程安全性进行分类,分别介绍非线程安全与线程安全的实现方…...
【软件】教务系统成绩提交工具使用步骤
【软件】教务系统成绩提交工具使用步骤 零、快速开始 安装 与大多数软件一样,安装步骤很简单,一直点击“下一步”即可快速完成安装,安装完成后,在桌面会有一个软件图标,双击即可打开软件主界面。 导入成绩到Excel中…...
IPsec协议,网络安全的秘密
IPsec概述 IPsec是一组基于网络层的安全协议,是保护IP数据包在网络传输过程中保持安全、隐秘以及真实。通过对IP数据包进行一些加密、认证,来防止数据在传输过程中被窃取、篡改甚至伪造,IPsec在企业内部网络的通信、远程办公、云服务连接等场…...
浅谈下Spring MVC的执行流程
什么是Spring MVC Spring MVC是一个基于Java的Web框架,用于构建Web应用程序。 它是Spring Framework的一部分,它提供了模型-视图-控制器(MVC)架构。 支持RESTful风格的URL请求,易于与其他视图技术集成,如…...
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像 一、资源准备1.1 镜像文件1.2 刷机工具1.3 ubuntu20.04 docker镜像(具备demon无人机所需各种驱动) 二、开始刷机(安装ubuntu22.04系统)2.1 进入刷机状态2.2 刷机 三、docker…...
GitLab 服务变更提醒:中国大陆、澳门和香港用户停止提供服务(GitLab 服务停止)
目录 前言 一. 变更详情 1. 停止服务区域 2. 邮件通知 3. 新的服务提供商 4. 关键日期 5. 行动建议 二. 迁移指南 三. 注意事项 四. 相关推荐 前言 近期,许多位于中国大陆、澳门和香港的 GitLab 用户收到了一封来自 GitLab 官方的重要通知。根据这封邮件…...
主成分分析是线性降维方法
主成分分析是线性降维方法 主成分分析(PCA)是一种常用的线性降维方法。它通过线性变换将原始数据映射到新的坐标系中,使得数据在新坐标系中的第一个坐标(第一个主成分)具有最大的方差,以此类推,…...
Webpack在Vue CLI中的应用
webpack 作为目前最流行的项目打包工具,被广泛使用于项目的构建和开发过程中,其实说它是打包工具有点大材小用了,我个人认为它是一个集前端自动化、模块化、组件化于一体的可拓展系统,你可以根据自己的需要来进行一系列的配置和安…...
继承超详细介绍
一 、继承 1 继承的概念 继承是面向对象程序设计使得代码可以复用的最重要手段,它使得我们可以在原有类的特性的基础上进行扩展,增加方法和属性(成员函数与成员变量),这样产生新的类,叫作派生类。继承呈现了…...
wordpress调用指定ID分类下浏览最多的内容
要在WordPress中调用指定ID分类下浏览最多的内容,你可以通过以下方法实现: <?php $post_num 8; // 设置调用条数 $wdpidproduct 2; // 假设这是你要查询的分类ID $args array(post_password > ,post_status > publish, // wodepress.comca…...
18.springcloud_openfeign之扩展组件二
文章目录 一、前言二、子容器默认组件FeignClientsConfigurationDecoder的注入Contract约定 对注解的支持对类上注解的支持对方法上注解的支持对参数上注解的支持MatrixVariablePathVariableRequestParamRequestHeaderSpringQueryMapRequestPartCookieValue FormattingConversi…...
FreePBX修改IP地址和端口以及添加SSL证书开启HTTPS访问
最近给单位部署了freepbx网络电话系统,我的系统是安装在ibm x3650 m4物理机上的,iso镜像下载后直接用Rufus烧录到U盘,服务器上先做好了raid1,插上U盘重启服务器开撸。安装过程略过了,在虚拟机上安装就不用那么麻烦。 …...
运算符 - 算术、关系、逻辑运算符
引言 在编程中,运算符是用于执行特定操作的符号。C 提供了多种类型的运算符,包括算术运算符、关系运算符和逻辑运算符等。理解这些运算符及其用法对于编写高效且无误的代码至关重要。本文将详细介绍 C 中的这三种基本运算符,并通过实例帮助读…...
大模型-ChatGLM2-6B模型部署与微调记录
大模型-ChatGLM2-6B模型部署与微调记录 模型权重下载: 登录魔塔社区:https://modelscope.cn/models/ZhipuAI/chatglm2-6b 拷贝以下代码执行后,便可快速权重下载到本地 # 备注:最新模型版本要求modelscope > 1.9.0 # pip insta…...
RDFS—RDF模型属性扩展解析
目录 前言1. 什么是RDFS?1.1 RDFS的核心概念1.2 RDFS与RDF的区别 2. RDFS的基础概念2.1 类(Class)2.2 属性(Property)2.3 关系(Relation)2.4 定义域(Domain)2.5 值域&…...
pyqt和pycharm环境搭建
安装 python安装: https://www.python.org/downloads/release/python-3913/ python3.9.13 64位(记得勾选Path环境变量) pycharm安装: https://www.jetbrains.com/pycharm/download/?sectionwindows community免费版 换源: pip config se…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
