278 lines
7.2 KiB
C#
278 lines
7.2 KiB
C#
using System;
|
|||
|
|
using System.ComponentModel;
|
||
|
|
using System.Drawing;
|
||
|
|
using System.Drawing.Drawing2D;
|
||
|
|
using System.Windows.Forms;
|
||
|
|
|
||
|
|
namespace Controls
|
||
|
|
{
|
||
|
|
[ToolboxItem(true)]
|
||
|
|
[Description("一个用于显示通信状态的LED指示器控件")]
|
||
|
|
public partial class UCLed : UserControl
|
||
|
|
{
|
||
|
|
private Color _onColor = Color.Green;
|
||
|
|
private Color _offColor = Color.Red;
|
||
|
|
private Color _blinkColor = Color.Yellow;
|
||
|
|
private Color _textColor = Color.White;
|
||
|
|
private string _statusText = "NG";
|
||
|
|
private bool _isOn = false;
|
||
|
|
private bool _isBlinking = false;
|
||
|
|
private bool _blinkState = false;
|
||
|
|
private int _blinkInterval = 500; // 默认闪烁间隔(毫秒)
|
||
|
|
private Timer _blinkTimer;
|
||
|
|
|
||
|
|
private int _cornerRadius = 10; // 新增:控制圆角半径的字段
|
||
|
|
|
||
|
|
public UCLed()
|
||
|
|
{
|
||
|
|
InitializeComponent();
|
||
|
|
SetStyle(ControlStyles.SupportsTransparentBackColor |
|
||
|
|
ControlStyles.OptimizedDoubleBuffer |
|
||
|
|
ControlStyles.AllPaintingInWmPaint |
|
||
|
|
ControlStyles.UserPaint, true);
|
||
|
|
this.BackColor = Color.Transparent;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnHandleCreated(EventArgs e)
|
||
|
|
{
|
||
|
|
base.OnHandleCreated(e);
|
||
|
|
InitializeTimer();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InitializeTimer()
|
||
|
|
{
|
||
|
|
if (_blinkTimer == null)
|
||
|
|
{
|
||
|
|
_blinkTimer = new Timer();
|
||
|
|
_blinkTimer.Tick += BlinkTimer_Tick;
|
||
|
|
_blinkTimer.Interval = _blinkInterval;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue(typeof(Color), "Green")]
|
||
|
|
public Color OnColor
|
||
|
|
{
|
||
|
|
get => _onColor;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_onColor != value)
|
||
|
|
{
|
||
|
|
_onColor = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue(typeof(Color), "Red")]
|
||
|
|
public Color OffColor
|
||
|
|
{
|
||
|
|
get => _offColor;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_offColor != value)
|
||
|
|
{
|
||
|
|
_offColor = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue(typeof(Color), "Yellow")]
|
||
|
|
public Color BlinkColor
|
||
|
|
{
|
||
|
|
get => _blinkColor;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_blinkColor != value)
|
||
|
|
{
|
||
|
|
_blinkColor = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue(typeof(Color), "White")]
|
||
|
|
public Color TextColor
|
||
|
|
{
|
||
|
|
get => _textColor;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_textColor != value)
|
||
|
|
{
|
||
|
|
_textColor = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue(10)]
|
||
|
|
public int CornerRadius
|
||
|
|
{
|
||
|
|
get => _cornerRadius;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_cornerRadius != value)
|
||
|
|
{
|
||
|
|
_cornerRadius = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
[Category("外观")]
|
||
|
|
[DefaultValue("NG")]
|
||
|
|
public string StatusText
|
||
|
|
{
|
||
|
|
get => _statusText;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_statusText != value)
|
||
|
|
{
|
||
|
|
_statusText = value;
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("行为")]
|
||
|
|
[DefaultValue(false)]
|
||
|
|
public bool IsOn
|
||
|
|
{
|
||
|
|
get => _isOn;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_isOn != value)
|
||
|
|
{
|
||
|
|
_isOn = value;
|
||
|
|
if (!_isBlinking)
|
||
|
|
{
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("行为")]
|
||
|
|
[DefaultValue(false)]
|
||
|
|
public bool IsBlinking
|
||
|
|
{
|
||
|
|
get => _isBlinking;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_isBlinking != value)
|
||
|
|
{
|
||
|
|
_isBlinking = value;
|
||
|
|
if (_isBlinking)
|
||
|
|
_blinkTimer?.Start();
|
||
|
|
else
|
||
|
|
{
|
||
|
|
_blinkTimer?.Stop();
|
||
|
|
_blinkState = false;
|
||
|
|
}
|
||
|
|
Invalidate();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Category("行为")]
|
||
|
|
[DefaultValue(500)]
|
||
|
|
public int BlinkInterval
|
||
|
|
{
|
||
|
|
get => _blinkInterval;
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (_blinkInterval != value)
|
||
|
|
{
|
||
|
|
_blinkInterval = value;
|
||
|
|
if (_blinkTimer != null && !DesignMode)
|
||
|
|
{
|
||
|
|
_blinkTimer.Interval = _blinkInterval;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
private void BlinkTimer_Tick(object sender, EventArgs e)
|
||
|
|
{
|
||
|
|
_blinkState = !_blinkState;
|
||
|
|
this.BeginInvoke(new Action(() => this.Invalidate()));
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnPaint(PaintEventArgs e)
|
||
|
|
{
|
||
|
|
base.OnPaint(e);
|
||
|
|
Graphics g = e.Graphics;
|
||
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
|
|
|
||
|
|
Color currentColor;
|
||
|
|
|
||
|
|
if (_isBlinking)
|
||
|
|
{
|
||
|
|
currentColor = _blinkState ? _blinkColor : (_isOn ? _onColor : _offColor);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
currentColor = _isOn ? _onColor : _offColor;
|
||
|
|
}
|
||
|
|
|
||
|
|
using (GraphicsPath path = CreateRoundedRectangle(ClientRectangle, _cornerRadius))
|
||
|
|
using (SolidBrush backBrush = new SolidBrush(currentColor))
|
||
|
|
{
|
||
|
|
g.FillPath(backBrush, path);
|
||
|
|
}
|
||
|
|
|
||
|
|
using (Brush textBrush = new SolidBrush(_textColor))
|
||
|
|
{
|
||
|
|
StringFormat sf = new StringFormat();
|
||
|
|
sf.Alignment = StringAlignment.Center;
|
||
|
|
sf.LineAlignment = StringAlignment.Center;
|
||
|
|
g.DrawString(_statusText, Font, textBrush, ClientRectangle, sf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private GraphicsPath CreateRoundedRectangle(Rectangle bounds, int radius)
|
||
|
|
{
|
||
|
|
int diameter = radius * 2;
|
||
|
|
Size size = new Size(diameter, diameter);
|
||
|
|
Rectangle arc = new Rectangle(bounds.Location, size);
|
||
|
|
GraphicsPath path = new GraphicsPath();
|
||
|
|
|
||
|
|
if (radius == 0)
|
||
|
|
{
|
||
|
|
path.AddRectangle(bounds);
|
||
|
|
return path;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 左上角
|
||
|
|
path.AddArc(arc, 180, 90);
|
||
|
|
|
||
|
|
// 右上角
|
||
|
|
arc.X = bounds.Right - diameter;
|
||
|
|
path.AddArc(arc, 270, 90);
|
||
|
|
|
||
|
|
// 右下角
|
||
|
|
arc.Y = bounds.Bottom - diameter;
|
||
|
|
path.AddArc(arc, 0, 90);
|
||
|
|
|
||
|
|
// 左下角
|
||
|
|
arc.X = bounds.Left;
|
||
|
|
path.AddArc(arc, 90, 90);
|
||
|
|
|
||
|
|
path.CloseFigure();
|
||
|
|
return path;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|