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+ 自定义液晶数字显示控件实现icon-default.png?t=O83Ahttps://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日

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebRTC服务质量(12)- Pacer机制(04) 向Pacer中插入数据

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…

C#实现调用DLL 套壳读卡程序(桌面程序开发)

背景 正常业务已经支持 读三代卡了&#xff0c;前端调用医保封装好的服务就可以了&#xff0c;但是长护要读卡&#xff0c;就需要去访问万达&#xff0c;他们又搞了一套读卡的动态库&#xff0c;为了能够掉万达的接口&#xff0c;就需要去想办法调用它们提供的动态库方法&…

低代码开发平台排名2024

低代码开发平台在过去几年中迅速崛起&#xff0c;成为企业数字化转型的重要工具。这些平台通过可视化界面和拖放组件&#xff0c;使业务人员和技术人员都能快速构建应用程序&#xff0c;大大缩短了开发周期。以下是一些在2024年值得关注和使用的低代码开发平台。 一、Zoho Cre…

rocketmq-push模式-消费侧重平衡-类流程图分析

1、观察consumer线程 使用arthas分析 MQClientFactoryScheduledThread 定时任务线程 定时任务线程&#xff0c;包含如下任务&#xff1a; 每2分钟更新nameServer列表 每30秒更新topic的路由信息 每30秒检查broker的存活&#xff0c;发送心跳请求 每5秒持久化消费队列的offset…

群落生态学研究进展▌Hmsc包对于群落生态学假说的解读、Hmsc包开展单物种和多物种分析的技术细节及Hmsc包的实际应用

HMSC&#xff08;Hierarchical Species Distribution Models&#xff09;是一种用于预测物种分布的统计模型。它在群落生态学中的应用广泛&#xff0c;可以帮助科学家研究物种在不同环境条件下的分布规律&#xff0c;以及预测物种在未来环境变化下的潜在分布范围。 举例来说&a…

影视仓最新接口+内置本包方法的研究(2024.12.27)

近日喜欢上了研究影视的本地仓库内置&#xff0c;也做了一个分享到了群里。 内置本地仓库包的好处很明显&#xff0c;当前线路接口都是依赖网络上的代码站存放&#xff0c;如果维护者删除那就GG。 虽然有高手制作了很多本地包&#xff0c;但推送本地包到APP&#xff0c;难倒一片…

教育元宇宙的优势与核心功能解析

随着科技的飞速发展&#xff0c;教育领域正迎来一场前所未有的变革。教育元宇宙作为新兴的教育形态&#xff0c;以其独特的优势和丰富的功能&#xff0c;正在逐步改变我们的学习方式。本文将深入探讨教育元宇宙的优势以及其核心功能&#xff0c;为您揭示这一未来教育的新趋势。…

多个微服务 Mybatis 过程中出现了Invalid bound statement (not found)的特殊问题

针对多个微服务的场景&#xff0c;记录一下这个特殊问题&#xff1a; 如果启动类上用了这个MapperScan注解 在resource 目录下必须建相同的 com.demo.biz.mapper 目录结构&#xff0c;否则会加载不到XML资源文件 。 并且切记是com/demo/biz 这样的格式创建&#xff0c;不要使用…

Java基础知识(四) -- 面向对象(下)

1.类变量和类方法 1.1 类变量背景 有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩? 思路分析: 核心在于如何让变量count被所有对象共享 public class Child {private String name;// 定义静态变量(所有Child对象共享)public static int count 0;p…

Linux系统之stat命令的基本使用

Linux系统之stat命令的基本使用 一、stat命令 介绍二、stat命令帮助2.1 查询帮助信息2.2 stat命令的帮助解释 三、stat命令的基本使用3.1 查询文件信息3.2 查看文件系统状态3.3 使用格式化输出3.4 以简洁形式打印信息 四、注意事项 一、stat命令 介绍 stat 命令用于显示文件或文…

雷池 WAF 搭配阿里云 CDN 使用教程

雷池 WAF&#xff08;Web Application Firewall&#xff09;是一款强大的网络安全防护产品&#xff0c;通过实时流量分析和精准规则拦截&#xff0c;有效抵御各种网络攻击。在部署雷池 WAF 的同时&#xff0c;结合阿里云 CDN&#xff08;内容分发网络&#xff09;可以显著提升网…

蓝桥杯速成教程{三}(adc,i2c,uart)

目录 一、adc 原理图​编辑引脚配置 Adc通道使能配置 实例测试 ​编辑效果显示 案例程序 badc 按键相关函数 测量频率占空比 main 按键的过程 显示界面的过程 二、IIC通信-eeprom 原理图AT24C02 引脚配置 不可用状态&#xff0c;用的软件IIC 官方库移植 At24c02手册 ​编辑…

Semantic Segmentation Editor标注工具

https://github.com/Hitachi-Automotive-And-Industry-Lab/semantic-segmentation-editor https://docs.meteor.com/about/install.html https://v2-docs.meteor.com/install.html 安装指定版本的meteor curl https://install.meteor.com/\?release\2.12 | sh ubuntu18 安…

攻防世界web新手第四题easyphp

<?php highlight_file(__FILE__); $key1 0; $key2 0;$a $_GET[a]; $b $_GET[b];if(isset($a) && intval($a) > 6000000 && strlen($a) < 3){if(isset($b) && 8b184b substr(md5($b),-6,6)){$key1 1;}else{die("Emmm...再想想&quo…

vxe-table 实现跨行按钮同时控制两行的编辑状态

vxe-table 写可编辑表格用起来很爽吧&#xff01;有没有遇到下面这种要用一个跨行按钮&#xff0c;控制两行编辑框是否可编辑的情况。是不是官网的方法不好实现了&#xff1f;那么这个应该怎么实现呢。最近刚好碰到这个问题。说下个人的实现思路。 其实也简单&#xff0c;既然官…

ES 磁盘使用率检查及处理方法

文章目录 1. 检查原因2. 检查方法3. 处理方法3.1 清理数据3.2 再次检查磁盘使用率 1. 检查原因 磁盘使用率在 85%以下&#xff0c;ES 可正常运行&#xff0c;达到 85%及以上会影响 PEIM 数据存储。 在 ES 磁盘分配分片控制策略中&#xff0c;为了保护数据节点的安全&#xff0…

论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 王志豪&#xff0c;厦门大学博士生 刘诗雨&#xff0c;厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型&#xff08;LLMs&#xff…

【Linux 系统负载详情解析】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

欲海航舟:探寻天性驱动下的欲望演变与人生驾驭

欲海航舟&#xff1a;探寻天性驱动下的欲望演变与人生驾驭。 欲望之源起&#xff0c;本乎天性。 鸿蒙初辟&#xff0c;生灵乍现&#xff0c;欲望即随人之性灵而生&#xff0c;如花木之根柢&#xff0c;虽隐匿于地下&#xff0c;却为生长之根基。 人之初诞&#xff0c;懵懂无…

WebRTC 环境搭建

主题 本文主要描述webrtc开发过程中所需的环境搭建 环境&#xff1a; 运行环境&#xff1a;ubuntu20.04 Node.js环境搭建 安装编译 Node.js 所需的依赖包: sudo apt-get updatesudo apt-get install -y build-essential libssl-dev下载 Node.js 源码: curl -sL https://…