C#自定义控件开发(2)—LED指示灯
下面来开发一个LED指示灯控件,如下:
设计属性包括:
外环宽度,外环间隙,内环间隙,颜色【五种】,当前值。
由于该LED指示灯基本是完全独立设计的,并不是在某个控件的基础上进行的开发,因此,这里使
用用户控件的方式进行开发。通过GDI+方式对控件进行绘制。GDI的坐标系如下:
首先绘制外环,然后绘制内圆。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace JSControl { public partial class LedControl : UserControl { public LedControl() { InitializeComponent(); this.Size = new Size(40,40);//初始化控件大小 } #region Filed private float outWidth = 4.0f; [Browsable(true)] [Category("自定义属性")] [Description("外环宽度")] public float OutWidth { get { return outWidth; } set { if (value <= 0 || value > 0.1f * this.Width) { return; } outWidth = value; this.Invalidate(); } } private float outGap = 3.0f; [Browsable(true)] [Category("自定义属性")] [Description("外环间隙")] public float OutGap { get { return outGap; } set { if (value <= 0 || value > 0.1f * this.Width || inGap <= value) { return; } outGap = value; this.Invalidate(); } } private float inGap = 8.0f; [Browsable(true)] [Category("自定义属性")] [Description("内环间隙")] public float InGap { get { return inGap; } set { if (value <= 0 || value <= outGap) { return; } inGap = value; this.Invalidate(); } } private Color color1 = Color.Gray; [Browsable(true)] [Category("自定义属性")] [Description("指示灯颜色")] public Color Color1 { get { return color1; } set { color1 = value; this.Invalidate(); } } private Color color2 = Color.LimeGreen; [Browsable(true)] [Category("自定义属性")] [Description("LimeGreen")] public Color Color2 { get { return color2; } set { color2 = value; this.Invalidate(); } } private Color color3 = Color.Red; [Browsable(true)] [Category("自定义属性")] [Description("Red")] public Color Color3 { get { return color3; } set { color3 = value; this.Invalidate(); } } private Color color4 = Color.DarkGoldenrod; [Browsable(true)] [Category("自定义属性")] [Description("DarkGoldenrod")] public Color Color4 { get { return color4; } set { color4 = value; this.Invalidate(); } } private Color color5 = Color.Blue; [Browsable(true)] [Category("自定义属性")] [Description("Blue")] public Color Color5 { get { return color5; } set { color5 = value; this.Invalidate(); } } //指示灯颜色索引 private int currentValue = 0; [Browsable(true)] [Category("自定义属性")] [Description("当前值")] public int CurrentValue { get { return currentValue; } set { if (value > 4 || value < 0) { return; } currentValue = value; this.Invalidate(); } } #endregion #region verride private Graphics g; private Pen p;//画笔 private SolidBrush sb;//画刷 private int width;//控件宽度 private int height;//控件高度 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); g = e.Graphics; width = this.Width; height = this.Height; //这里是为了设置渲染效果,消除锯齿,高效果显示 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; if (inGap>0.5f*this.Height||inGap>0.5f*this.Width) { return; } Color CurrentColor = GetCurrentColor(this.currentValue); //设置画笔的宽度 p = new Pen(CurrentColor, outWidth); //先绘制外环 RectangleF rec = new RectangleF(outGap, outGap, this.width - 2 * outGap, this.height - 2 * outGap); g.DrawEllipse(p, rec); sb = new SolidBrush(CurrentColor); //再绘制内圆 rec = new RectangleF(inGap, inGap, this.width - 2 * inGap, this.height - 2 * inGap); g.FillEllipse(sb, rec); } #endregion #region Private Methods /// <summary> /// 设置控件颜色 /// </summary> /// <returns></returns> private Color GetCurrentColor(int currentColor) { List<Color> ColorList = new List<Color>(); ColorList.Add(color1); ColorList.Add(color2); ColorList.Add(color3); ColorList.Add(color4); ColorList.Add(color5); return ColorList[currentValue]; } #endregion } }
this.Invalidate()表示进行重绘,调用它后将会执行
protected override void OnPaint(PaintEventArgs e){}中的代码进行重绘。
生成后,将和其他控件一样可以看到其属性。
4556
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端