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日

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

药片缺陷检测数据集,8625张图片,使用YOLO,PASICAL VOC XML,COCO JSON格式标注,可识别药品是否有缺陷,是否完整

药片缺陷检测数据集&#xff0c;8625张图片&#xff0c;使用YOLO&#xff0c;PASICAL VOC XML&#xff0c;COCO JSON格式标注&#xff0c;可识别药品是否有缺陷&#xff0c;是否完整 有缺陷的标注信息&#xff1a; 无缺陷的标注信息 数据集下载&#xff1a; yolov11:https://d…

jenkins集成工具(一)部署php项目

目录 什么是CI 、CD Jenkins集成工具 一、Jenkins介绍 二、jenkins的安装和部署 环境部署 安装jenkins 安装gitlab 配置镜像源进行安装 修改密码 安装git工具 上传测试代码 Jenkins部署php项目wordpress 发布php代码 安装插件 测试代码发布 实现发布成功发送邮件…

Web开发:ORM框架之使用Freesql的分表分页写法

一、自动分表&#xff08;高版本可用&#xff09; 特性写法 //假如是按月分表&#xff1a;[Table(Name "log_{yyyyMM}", AsTable "createtime2022-1-1(1 month)")]注意&#xff1a;①需包含log_202201这张表 ②递增规律是一个月一次&#xff0c;确保他们…

【UE5.3.2】生成vs工程并rider打开

Rider是跨平台的,UE也是,当前现在windows上测试首先安装ue5.3.2 会自动有右键的菜单: windows上,右键,生成vs工程 生成的结果 sln默认是vs打开的,我的是vs2022,可以open with 选择 rider :Rider 会弹出 RiderLink是什么插

FFmpeg在python里推流被处理过的视频流

链式算法处理视频流 视频源是本地摄像头 # codinggbk # 本地摄像头直接推流到 RTMP 服务器 import cv2 import mediapipe as mp import subprocess as sp# 初始化 Mediapipe mp_drawing mp.solutions.drawing_utils mp_drawing_styles mp.solutions.drawing_styles mp_holis…

【工具】—— SpringBoot3.x整合swagger

Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务的接口文档。Swagger简单说就是可以帮助生成接口说明文档&#xff0c;操作比较简单添加注解说明&#xff0c;可以自动生成格式化的文档。 项目环境 jdk17SpringBoot 3.4.0Sp…

Docker 部署 plumelog 最新版本 实现日志采集

1.配置plumelog.yml version: 3 services:plumelog:#此镜像是基于plumelog-3.5.3版本image: registry.cn-hangzhou.aliyuncs.com/k8s-xiyan/plumelog:3.5.3container_name: plumelogports:- "8891:8891"environment:plumelog.model: redisplumelog.queue.redis.redi…

图像处理-Ch5-图像复原与重建

Ch5 图像复原 文章目录 Ch5 图像复原图像退化与复原(Image Degradation and Restoration)噪声模型(Noise Models)i.i.d.空间随机噪声(Generating Spatial Random Noise with a Specified Distribution)周期噪声(Periodic Noise)估计噪声参数(Estimating Noise Parameters) 在仅…

在vscode的ESP-IDF中使用自定义组件

以hello-world为例&#xff0c;演示步骤和注意事项 1、新建ESP-IDF项目 选择模板 从hello-world模板创建 2、打开项目 3、编译结果没错 正在执行任务: /home/azhu/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/azhu/esp/v5.1/esp-idf/tools/idf_size.py /home…

WordPress网站中如何修复504错误

504网关超时错误是非常常见的一种网站错误。这种错误发生在上游服务器未能在规定时间内完成请求的情况下&#xff0c;对访问者而言&#xff0c;出现504错误无疑会对访问体验大打折扣&#xff0c;从而对网站的转化率和收入造成负面影响。 504错误通常源于服务器端或网站本身的问…

C++——运算符重载

一、运算符重载 ①含义 函数重载或函数多态&#xff1a;同名函数完成相同的基本操作 C将重载的概念扩展到运算符上&#xff0c;于是出现了运算符重载 C中有很多运算符已经被重载 *运算符&#xff0c;运用于地址&#xff0c;可以得到存储在这个地址的值&#xff1b;运用于两个…

抖去推碰一碰系统技术源码/open SDK转发技术开发

抖去推碰一碰系统技术源码/open SDK转发技术开发 碰一碰智能系统#碰碰卡系统#碰一碰系统#碰一碰系统技术源头开发 碰碰卡智能营销系统开发是一种集成了人工智能和NFC技术的工具&#xff0c;碰碰卡智能营销系统通过整合数据分析、客户关系管理、自动化营销活动、多渠道整合和个…

【Unity3D】ECS入门学习(六)状态组件 ISystemStateComponentData

当需要获知组件是否被销毁时&#xff0c;ECS是没有回调告知的&#xff0c;因此可以将组件继承于ISystemStateComponentData接口&#xff0c;这样即使组件的实体被销毁了&#xff0c;该组件本身是不会消失的&#xff0c;所以可以通过在组件实体销毁后&#xff0c;去设置状态组件…

期权懂|如何计算期权卖方平仓后的盈利?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 如何计算期权卖方平仓后的盈利&#xff1f; 期权卖方平仓后的盈利计算涉及多个因素&#xff0c;包括期权的交易价格、平仓价格以及权利金的变动等。 交易价格&#xff1a;期权卖…

ARM64 Windows 10 IoT工控主板运行x86程序效率测试

ARM上的 Windows 10 IoT 企业版支持仿真 x86 应用程序&#xff0c;而 ARM上的 Windows 11 IoT 企业版则支持仿真 x86 和 x64 应用程序。英创推出的名片尺寸ARM64工控主板ESM8400&#xff0c;可预装正版Windows 10 IoT企业版操作系统&#xff0c;x86程序可无需修改而直接在ESM84…

【Ubuntu 20.4安装截图软件 flameshot 】

步骤一&#xff1a; 安装命令&#xff1a; sudo apt-get install flameshot 步骤二&#xff1a; 设置快捷方式&#xff1a; Ubuntu20.4 设置菜单&#xff0c;点击 号 步骤三&#xff1a; 输入软件名称&#xff0c; 软件快捷命令&#xff08;flameshot gui&#xff09;&am…

NAT 技术如何解决 IP 地址短缺问题?

NAT 技术如何解决 IP 地址短缺问题&#xff1f; 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 随着互联网的普及和发展&#xff0c;IP 地址的需求量迅速增加。尤其是 IPv4 地址&…

算法题(17):删除有序数组中的重复项

审题&#xff1a; 需要我们原地删除数组中的重复数据&#xff0c;并输出有效数据个数 思路&#xff1a; 方法一&#xff1a;原地解法&#xff08;双指针&#xff09; 设置left指针指向当前的非重复数据&#xff0c;right负责遍历数组&#xff0c;遇到和left指向的数据不同的数据…

LaTeXChecker:使用 Python 实现以主 TEX 文件作为输入的 LaTeX 检查和统计工具

使用 Python 实现以主 TEX 文件作为输入的 LaTeX 检查和统计工具&#xff0c;适用于包括但不限于一稿多模板的复杂排版方式&#xff0c;工具以只读模式运行。 Github 链接&#xff1a;https://github.com/BatchClayderman/LaTeXChecker import os from sys import argv, exec…

Web API和Web Services的区分

前些年一提及自动化测试&#xff0c;大多是指UI界面层的自动化测试。近几年&#xff0c;随着分层自动化测试概念的兴起&#xff0c;以及自动化测试自身的发展与细分&#xff0c;自动化测试包含了更多的内容。 API(Application ProgrammingInterface&#xff0c;应用程序编程接…