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日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值