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

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.lryc.cn/news/511033.html

相关文章:

  • 在交叉编译中,常见的ELF(elf)到底是什么意思?
  • Unity开发AR之Vuforia-MultiTarget笔记
  • 深入解析 Oracle 的聚合函数 ROLLUP
  • Wend看源码-Java-集合学习(List)
  • 【软件】教务系统成绩提交工具使用步骤
  • IPsec协议,网络安全的秘密
  • 浅谈下Spring MVC的执行流程
  • khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像
  • GitLab 服务变更提醒:中国大陆、澳门和香港用户停止提供服务(GitLab 服务停止)
  • 主成分分析是线性降维方法
  • Webpack在Vue CLI中的应用
  • 继承超详细介绍
  • wordpress调用指定ID分类下浏览最多的内容
  • 18.springcloud_openfeign之扩展组件二
  • FreePBX修改IP地址和端口以及添加SSL证书开启HTTPS访问
  • 运算符 - 算术、关系、逻辑运算符
  • 大模型-ChatGLM2-6B模型部署与微调记录
  • RDFS—RDF模型属性扩展解析
  • pyqt和pycharm环境搭建
  • salesforce 控制 Experience Cloud 站点用户可以看到哪些用户
  • 【玩转OCR】 | 腾讯云智能结构化OCR在多场景的实际应用与体验
  • 面试题整理20----什么是蓝绿部署、灰度发布、金丝雀发布他们有什么区别?
  • c语言传参数路径太长,导致无法获取参数
  • React性能优化:构建更高效的应用
  • python+PyMuPDF库:(一)创建pdf文件及内容读取和写入
  • vue3配置测试环境、开发环境、生产环境
  • Jsonlizer,一个把C++各类数据转成 Json 结构体的玩意儿
  • Qt仿音乐播放器:设置窗口、部件属性
  • 使用 .NET 6 或 .NET 8 上传大文件
  • 基于特征工程(pca分析)、小波去噪以及数据增强,同时采用基于注意力机制的BiLSTM、随机森林、ARIMA模型进行序列数据预测