调用方法
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日