C#--自定義控制元件-開發LED指示燈控制元件
阿新 • • 發佈:2021-01-11
以下是學習筆記:
參考:https://www.bilibili.com/video/BV1eQ4y1M7ZY?p=5
效果如下:
思考:實現以上效果要用到哪些屬性
顏色,是否有邊框,外環寬度,是否高亮,中心顏色,是否閃爍,顏色列表,閃爍的頻率
如果是開關,就需要bool型別 True,False顏色
如果是多種狀態,當前值數值型別
常規操作:
一,自定義LED顯示的控制元件
1,新增“使用者控制元件”,命名MyLED
2,編寫使用者控制元件的MyLED的程式碼
public partial class MyLED : UserControl { public MyLED() { InitializeComponent(); #region 【1】設定雙緩衝等屬性 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); #endregion } #region 【2】定義三個欄位 private Graphics g; private Pen p; private SolidBrush sb; #endregion #region 【3】新增一個設定Graphics的方法 private void SetGraphics(Graphics g) { //設定畫布的屬性 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; } #endregion #region 【4】根據實際控制元件分析的結果,建立屬性 private Color ledColor = Color.Green; [Category("jason控制元件屬性")] [Description("LED指示燈演示")] public Color LedColor { get { return ledColor; } set { ledColor = value; this.Invalidate(); } } #endregion #region 【5】建立重繪的事件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); g = e.Graphics;//獲取畫布 SetGraphics(g);//設定畫布 //情況1:如果寬度大於高度(以高度為準) if (this.Width > this.Height) { sb = new SolidBrush(ledColor); Rectangle rec=new Rectangle(1,1,this.Height-2,this.Height-2);//建立矩形 g.FillEllipse(sb,rec);//畫圓 } } #endregion }
3,重新生成後在工具箱裡面就可以看到MyLED的控制元件了,拖入後可以直接使用
注意:如果只有這個程式碼,那只有寬度大於高度的時候才會畫圓。
根據指示燈的功能需求,最終程式碼如下
public partial class MyLED : UserControl { public MyLED() { InitializeComponent(); #region 【1】設定雙緩衝等屬性 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); #endregion } #region 【2】定義三個欄位 private Graphics g; private Pen p; private SolidBrush sb; #endregion #region 【3】新增一個設定Graphics的方法 private void SetGraphics(Graphics g) { //設定畫布的屬性 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; } #endregion #region 【4】根據實際控制元件分析的結果,建立屬性 private Color ledColor = Color.Green; [Category("jason控制元件屬性")] [Description("LED指示燈演示")] public Color LedColor { get { return ledColor; } set { ledColor = value; this.Invalidate(); } } private bool isBorder = true; [Category("jason控制元件屬性")] [Description("是否有邊框")] public bool IsBorder { get { return isBorder; } set { isBorder = value; this.Invalidate(); } } private int borderWidth = 5; [Category("jason控制元件屬性")] [Description("圓環的寬度")] public int BorderWidth { get { return borderWidth; } set { borderWidth = value; this.Invalidate(); } } private int gapWidth = 5; [Category("jason控制元件屬性")] [Description("間隙的寬度")] public int GapWidth { get { return gapWidth; } set { gapWidth = value; this.Invalidate(); } } private bool isHighLight = true; [Category("jason控制元件屬性")] [Description("是否高亮")] public bool IsHighLight { get { return isHighLight; } set { isHighLight = value; this.Invalidate(); } } private Color centerColor = Color.White; [Category("jason控制元件屬性")] [Description("漸變中心的顏色")] public Color CenterColor { get { return centerColor; } set { centerColor = value; this.Invalidate(); } } #endregion #region 【5】建立重繪的事件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); g = e.Graphics;//獲取畫布 SetGraphics(g);//設定畫布 #region 1,畫一個圓 //if (this.Width > this.Height)//情況1:如果寬度大於高度(以高度為準) //{ // sb = new SolidBrush(ledColor); // Rectangle rec=new Rectangle(1,1,this.Height-2,this.Height-2);//建立矩形 // g.FillEllipse(sb,rec);//畫圓 //} //else//情況2:如果高度大於寬度(以寬度為準) //{ // sb = new SolidBrush(ledColor); // Rectangle rec = new Rectangle(1, 1, this.Width - 2, this.Width - 2);//建立矩形 // g.FillEllipse(sb, rec);//畫圓 //} //優化上面的程式碼 int LEDWidth = Math.Min(this.Width, this.Height); sb = new SolidBrush(ledColor); RectangleF rec = new RectangleF(1, 1, LEDWidth - 2, LEDWidth - 2);//建立矩形 g.FillEllipse(sb, rec);//畫圓 #endregion #region 2,在圓裡面畫一個圓環 //如果有邊框,那就畫一個圓環 if (isBorder)//引數這裡用欄位或屬性都可以,如果用屬性,程式要都走一些判斷的程式碼 { p = new Pen(this.BackColor, borderWidth);//使用背景色 //p = new Pen(Color.Red, borderWidth); float x = 1 + gapWidth + borderWidth * 0.5f; rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); g.DrawEllipse(p, rec);//畫圓環 } #endregion #region 3,漸變色繪製,是否高亮 if (isHighLight) { //if (isBorder) //{ // //先確定路徑 // GraphicsPath gp = new GraphicsPath(); // //float x = 1 + gapWidth + borderWidth * 0.5f;//如果座標是這個,會有點覆蓋圓環 // float x = 1 + gapWidth + borderWidth; // rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); // gp.AddEllipse(rec);//把矩形新增到路徑 // //漸變色畫刷,高亮 // PathGradientBrush pgb=new PathGradientBrush(gp);//把路徑傳入 // pgb.CenterColor = this.centerColor; // //設定有多少組顏色來漸變 // pgb.SurroundColors=new Color[] // { // ledColor // }; // g.FillPath(pgb,gp); //} //else //{ // //先確定路徑 // GraphicsPath gp = new GraphicsPath(); // float x = 1 ; // rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); // gp.AddEllipse(rec); // //漸變色畫刷,高亮 // PathGradientBrush pgb = new PathGradientBrush(gp); // pgb.CenterColor = this.centerColor; // pgb.SurroundColors = new Color[] // { // ledColor // }; // g.FillPath(pgb, gp); //} //優化上面的if else程式碼 GraphicsPath gp = new GraphicsPath(); float x = isBorder? 1 + gapWidth + borderWidth:1;//使用三元運算來判斷,優化程式碼 rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); gp.AddEllipse(rec);//把矩形新增到路徑 //漸變色畫刷,高亮 PathGradientBrush pgb = new PathGradientBrush(gp);//把路徑傳入 pgb.CenterColor = this.centerColor; //設定有多少組顏色來漸變 pgb.SurroundColors = new Color[] { ledColor }; g.FillPath(pgb, gp); } #endregion } #endregion }
圓的繪製的座標說明:
圓環的繪製的座標說明:
二,在專案中使用自定義控制元件
1,拖入MyLED控制元件
2,在主程式中根據狀態,來改變MyLED控制元件的顏色
bool myLEDStatus = true; this.myLED1.LedColor = myLEDStatus ? Color.LimeGreen : Color.Red;
上面用法比較通用,用起來麻煩,如果專案中只是true或false,對自定義控制元件進行改造
三,針對上述呼叫問題進行改造
1,增加三個屬性
private Color ledTrueColor = Color.Green; [Category("jason控制元件屬性")] [Description("TRUE的時候LED指示燈顏色")] public Color LedTrueColor { get { return ledTrueColor; } set { ledTrueColor = value; this.Invalidate(); } } private Color ledFalseColor = Color.Red; [Category("jason控制元件屬性")] [Description("False的時候LED指示燈顏色")] public Color LedFalseColor { get { return ledFalseColor; } set { ledFalseColor = value; this.Invalidate(); } } private bool ledStatus = true; [Category("jason控制元件屬性")] [Description("當前的狀態")] public bool LedStatus { get { return ledStatus; } set { ledStatus = value; this.Invalidate(); } }
2,把根據狀態來判斷顏色的程式碼寫在自定義控制元件裡面
3,在主程式中呼叫,一句程式碼就可以了
this.myLED1.LedStatus = true; //或者this.myLED1.LedStatus = false;
此時程式碼如下:
public partial class MyLED : UserControl { public MyLED() { InitializeComponent(); #region 【1】設定雙緩衝等屬性 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); #endregion } #region 【2】定義三個欄位 private Graphics g; private Pen p; private SolidBrush sb; #endregion #region 【3】新增一個設定Graphics的方法 private void SetGraphics(Graphics g) { //設定畫布的屬性 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; } #endregion #region 【4】根據實際控制元件分析的結果,建立屬性 private Color ledTrueColor = Color.Green; [Category("jason控制元件屬性")] [Description("TRUE的時候LED指示燈顏色")] public Color LedTrueColor { get { return ledTrueColor; } set { ledTrueColor = value; this.Invalidate(); } } private Color ledFalseColor = Color.Red; [Category("jason控制元件屬性")] [Description("False的時候LED指示燈顏色")] public Color LedFalseColor { get { return ledFalseColor; } set { ledFalseColor = value; this.Invalidate(); } } private bool ledStatus = true; [Category("jason控制元件屬性")] [Description("當前的狀態")] public bool LedStatus { get { return ledStatus; } set { ledStatus = value; this.Invalidate(); } } private Color ledColor = Color.Green; [Category("jason控制元件屬性")] [Description("LED指示燈演示")] public Color LedColor { get { return ledColor; } set { ledColor = value; this.Invalidate(); } } private bool isBorder = true; [Category("jason控制元件屬性")] [Description("是否有邊框")] public bool IsBorder { get { return isBorder; } set { isBorder = value; this.Invalidate(); } } private int borderWidth = 5; [Category("jason控制元件屬性")] [Description("圓環的寬度")] public int BorderWidth { get { return borderWidth; } set { borderWidth = value; this.Invalidate(); } } private int gapWidth = 5; [Category("jason控制元件屬性")] [Description("間隙的寬度")] public int GapWidth { get { return gapWidth; } set { gapWidth = value; this.Invalidate(); } } private bool isHighLight = true; [Category("jason控制元件屬性")] [Description("是否高亮")] public bool IsHighLight { get { return isHighLight; } set { isHighLight = value; this.Invalidate(); } } private Color centerColor = Color.White; [Category("jason控制元件屬性")] [Description("漸變中心的顏色")] public Color CenterColor { get { return centerColor; } set { centerColor = value; this.Invalidate(); } } #endregion #region 【5】建立重繪的事件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); g = e.Graphics;//獲取畫布 SetGraphics(g);//設定畫布 #region 1,畫一個圓 int LEDWidth = Math.Min(this.Width, this.Height); Color color = ledStatus ? ledTrueColor : ledFalseColor; //sb = new SolidBrush(ledColor); sb = new SolidBrush(color); RectangleF rec = new RectangleF(1, 1, LEDWidth - 2, LEDWidth - 2);//建立矩形 g.FillEllipse(sb, rec);//畫圓 #endregion #region 2,在圓裡面畫一個圓環 //如果有邊框,那就畫一個圓環 if (isBorder)//引數這裡用欄位或屬性都可以,如果用屬性,程式要都走一些判斷的程式碼 { p = new Pen(this.BackColor, borderWidth);//使用背景色 //p = new Pen(Color.Red, borderWidth); float x = 1 + gapWidth + borderWidth * 0.5f; rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); g.DrawEllipse(p, rec);//畫圓環 } #endregion #region 3,漸變色繪製,是否高亮 if (isHighLight) { GraphicsPath gp = new GraphicsPath(); float x = isBorder? 1 + gapWidth + borderWidth:1;//使用三元運算來判斷,優化程式碼 rec = new RectangleF(x, x, LEDWidth - 2 * x, LEDWidth - 2 * x); gp.AddEllipse(rec);//把矩形新增到路徑 //漸變色畫刷,高亮 PathGradientBrush pgb = new PathGradientBrush(gp);//把路徑傳入 pgb.CenterColor = this.centerColor; //設定有多少組顏色來漸變 pgb.SurroundColors = new Color[] { //ledColor color }; g.FillPath(pgb, gp); } #endregion } #endregion }