60

(五十二)c#Winform自定义控件-LED数字 - 冰封一夏

 5 years ago
source link: https://www.cnblogs.com/bfyx/p/11447261.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

http://www.hzhcontrols.com

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

396919-20190906172638353-469843149.png

396919-20190902181026374-347193363.gif

使用GID+画的,不了解的话请自行百度

添加一个类UCLEDNum ,继承UserControl

将数字拆分为单独的字,然后根据显示位置进行画出来,将显示位置定义为如下所示

    /* 显示位置序号
     *  ****1***
     *  *      *  
     *  6      2
     *  *      *
     *  ****7***
     *  *      *
     *  5      3
     *  *      *
     *  ****4***
     */

从上面可以看出,定义了1-7的位置,然后定义一个数字对应的显示列表

 1  private static Dictionary<char, int[]> m_nums = new Dictionary<char, int[]>();
 2         static UCLEDNum()
 3         {
 4             m_nums['0'] = new int[] { 1, 2, 3, 4, 5, 6 };
 5             m_nums['1'] = new int[] { 2, 3 };
 6             m_nums['2'] = new int[] { 1, 2, 5, 4, 7 };
 7             m_nums['3'] = new int[] { 1, 2, 7, 3, 4 };
 8             m_nums['4'] = new int[] { 2, 3, 6, 7 };
 9             m_nums['5'] = new int[] { 1, 6, 7, 3, 4 };
10             m_nums['6'] = new int[] { 1, 6, 5, 4, 3, 7 };
11             m_nums['7'] = new int[] { 1, 2, 3 };
12             m_nums['8'] = new int[] { 1, 2, 3, 4, 5, 6, 7 };
13             m_nums['9'] = new int[] { 1, 2, 3, 4, 7, 6 };
14             m_nums['-'] = new int[] { 7 };
15             m_nums[':'] = new int[0];
16             m_nums['.'] = new int[0];
17         }

你看到了还有“-”,“:”,“.”这3个符号,是为了时间和数字时候使用

然后定义一个矩形区域来用作绘画区域,并且在SizeChanged事件中赋值

Rectangle m_drawRect = Rectangle.Empty;
        void LEDNum_SizeChanged(object sender, EventArgs e)
        {
            m_drawRect = new Rectangle(1, 1, this.Width - 2, this.Height - 2);
        }

然后就是几个属性

 1   private char m_value = '0';
 2 
 3         [Description("值"), Category("自定义")]
 4         public char Value
 5         {
 6             get { return m_value; }
 7             set
 8             {
 9                 if (!m_nums.ContainsKey(value))
10                 {
11                     return;
12                 }
13                 if (m_value != value)
14                 {
15                     m_value = value;
16                     Refresh();
17                 }
18             }
19         }
20 
21         private int m_lineWidth = 8;
22 
23         [Description("线宽度,为了更好的显示效果,请使用偶数"), Category("自定义")]
24         public int LineWidth
25         {
26             get { return m_lineWidth; }
27             set
28             {
29                 m_lineWidth = value;
30                 Refresh();
31             }
32         }
33 
34         [Description("颜色"), Category("自定义")]
35         public override System.Drawing.Color ForeColor
36         {
37             get
38             {
39                 return base.ForeColor;
40             }
41             set
42             {
43                 base.ForeColor = value;
44             }
45         }

最重要的重绘

  1 protected override void OnPaint(PaintEventArgs e)
  2         {
  3             base.OnPaint(e);
  4             e.Graphics.SetGDIHigh();
  5             if (m_value == '.')
  6             {
  7                 Rectangle r2 = new Rectangle(m_drawRect.Left + (m_drawRect.Width - m_lineWidth) / 2, m_drawRect.Bottom - m_lineWidth * 2, m_lineWidth, m_lineWidth);
  8                 e.Graphics.FillRectangle(new SolidBrush(ForeColor), r2);
  9             }
 10             else if (m_value == ':')
 11             {
 12                 Rectangle r1 = new Rectangle(m_drawRect.Left + (m_drawRect.Width - m_lineWidth) / 2, m_drawRect.Top + (m_drawRect.Height / 2 - m_lineWidth) / 2, m_lineWidth, m_lineWidth);
 13                 e.Graphics.FillRectangle(new SolidBrush(ForeColor), r1);
 14                 Rectangle r2 = new Rectangle(m_drawRect.Left + (m_drawRect.Width - m_lineWidth) / 2, m_drawRect.Top + (m_drawRect.Height / 2 - m_lineWidth) / 2 + m_drawRect.Height / 2, m_lineWidth, m_lineWidth);
 15                 e.Graphics.FillRectangle(new SolidBrush(ForeColor), r2);
 16             }
 17             else
 18             {
 19                 int[] vs = m_nums[m_value];
 20                 if (vs.Contains(1))
 21                 {
 22                     GraphicsPath path = new GraphicsPath();
 23                     path.AddLines(new Point[] 
 24                 {
 25                     new Point(m_drawRect.Left + 2, m_drawRect.Top),
 26                     new Point(m_drawRect.Right - 2, m_drawRect.Top),
 27                     new Point(m_drawRect.Right - m_lineWidth-2, m_drawRect.Top+m_lineWidth),
 28                     new Point(m_drawRect.Left + m_lineWidth+2, m_drawRect.Top+m_lineWidth),
 29                     new Point(m_drawRect.Left + 2, m_drawRect.Top)
 30                 });
 31                     path.CloseAllFigures();
 32                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
 33                 }
 34 
 35                 if (vs.Contains(2))
 36                 {
 37                     GraphicsPath path = new GraphicsPath();
 38                     path.AddLines(new Point[] 
 39                 {
 40                     new Point(m_drawRect.Right, m_drawRect.Top),
 41                     new Point(m_drawRect.Right, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2),
 42                     new Point(m_drawRect.Right-m_lineWidth/2, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2+m_lineWidth/2),
 43                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2),
 44                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Top+m_lineWidth),
 45                     new Point(m_drawRect.Right, m_drawRect.Top)
 46                 });
 47                     path.CloseAllFigures();
 48                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
 49                 }
 50 
 51                 if (vs.Contains(3))
 52                 {
 53                     GraphicsPath path = new GraphicsPath();
 54                     path.AddLines(new Point[] 
 55                 {
 56                     new Point(m_drawRect.Right, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),
 57                     new Point(m_drawRect.Right, m_drawRect.Bottom),
 58                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Bottom-m_lineWidth),
 59                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),
 60                     new Point(m_drawRect.Right-m_lineWidth/2, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2-m_lineWidth/2),
 61                     new Point(m_drawRect.Right, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),                 
 62                 });
 63                     path.CloseAllFigures();
 64                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
 65                 }
 66 
 67                 if (vs.Contains(4))
 68                 {
 69                     GraphicsPath path = new GraphicsPath();
 70                     path.AddLines(new Point[] 
 71                 {
 72                     new Point(m_drawRect.Left + 2, m_drawRect.Bottom),
 73                     new Point(m_drawRect.Right - 2, m_drawRect.Bottom),
 74                     new Point(m_drawRect.Right - m_lineWidth-2, m_drawRect.Bottom-m_lineWidth),
 75                     new Point(m_drawRect.Left + m_lineWidth+2, m_drawRect.Bottom-m_lineWidth),
 76                     new Point(m_drawRect.Left + 2, m_drawRect.Bottom)
 77                 });
 78                     path.CloseAllFigures();
 79                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
 80                 }
 81 
 82                 if (vs.Contains(5))
 83                 {
 84                     GraphicsPath path = new GraphicsPath();
 85                     path.AddLines(new Point[] 
 86                 {
 87                     new Point(m_drawRect.Left, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),
 88                     new Point(m_drawRect.Left, m_drawRect.Bottom),
 89                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Bottom-m_lineWidth),
 90                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),
 91                     new Point(m_drawRect.Left+m_lineWidth/2, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2-m_lineWidth/2),
 92                     new Point(m_drawRect.Left, m_drawRect.Bottom-(m_drawRect.Height-m_lineWidth-4)/2),                 
 93                 });
 94                     path.CloseAllFigures();
 95                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
 96                 }
 97 
 98 
 99                 if (vs.Contains(6))
100                 {
101                     GraphicsPath path = new GraphicsPath();
102                     path.AddLines(new Point[] 
103                 {
104                     new Point(m_drawRect.Left, m_drawRect.Top),
105                     new Point(m_drawRect.Left, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2),
106                     new Point(m_drawRect.Left+m_lineWidth/2, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2+m_lineWidth/2),
107                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Top+(m_drawRect.Height-m_lineWidth-4)/2),
108                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Top+m_lineWidth),
109                     new Point(m_drawRect.Left, m_drawRect.Top)
110                 });
111                     path.CloseAllFigures();
112                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
113                 }
114 
115                 if (vs.Contains(7))
116                 {
117                     GraphicsPath path = new GraphicsPath();
118                     path.AddLines(new Point[] 
119                 {
120                     new Point(m_drawRect.Left+m_lineWidth/2, m_drawRect.Height/2+1),            
121                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Height/2-m_lineWidth/2+1),    
122                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Height/2-m_lineWidth/2+1),
123                     new Point(m_drawRect.Right-m_lineWidth/2, m_drawRect.Height/2+1),
124                     new Point(m_drawRect.Right-m_lineWidth, m_drawRect.Height/2+m_lineWidth/2+1),
125                     new Point(m_drawRect.Left+m_lineWidth, m_drawRect.Height/2+m_lineWidth/2+1),    
126                     new Point(m_drawRect.Left+m_lineWidth/2, m_drawRect.Height/2+1)
127                 });
128                     path.CloseAllFigures();
129                     e.Graphics.FillPath(new SolidBrush(ForeColor), path);
130                 }
131             }
132         }

完工,看下完整代码和效果

View Code

396919-20190902161447567-1699795960.png

 以上就是单个字符的了

=======================分割线==========================

下面对数字控件处理

添加一个用户控件UCLEDNums

添加一点属性

 1 private string m_value;
 2 
 3         [Description("值"), Category("自定义")]
 4         public string Value
 5         {
 6             get { return m_value; }
 7             set
 8             {
 9                 m_value = value;
10                 ReloadValue();
11             }
12         }
13 
14         private int m_lineWidth = 8;
15 
16         [Description("线宽度,为了更好的显示效果,请使用偶数"), Category("自定义")]
17         public int LineWidth
18         {
19             get { return m_lineWidth; }
20             set
21             {
22                 m_lineWidth = value;
23                 foreach (UCLEDNum c in this.Controls)
24                 {
25                     c.LineWidth = value;
26                 }
27             }
28         }
29 
30         [Description("颜色"), Category("自定义")]
31         public override System.Drawing.Color ForeColor
32         {
33             get
34             {
35                 return base.ForeColor;
36             }
37             set
38             {
39                 base.ForeColor = value;
40                 foreach (UCLEDNum c in this.Controls)
41                 {
42                     c.ForeColor = value;
43                 }
44             }
45         }
46 
47         public override RightToLeft RightToLeft
48         {
49             get
50             {
51                 return base.RightToLeft;
52             }
53             set
54             {
55                 base.RightToLeft = value;
56                 ReloadValue();
57             }
58         }

加载控件的函数

 1  private void ReloadValue()
 2         {
 3             try
 4             {
 5                 ControlHelper.FreezeControl(this, true);
 6                 this.Controls.Clear();
 7                 foreach (var item in m_value)
 8                 {
 9                     UCLEDNum uc = new UCLEDNum();
10                     if (RightToLeft == System.Windows.Forms.RightToLeft.Yes)
11                         uc.Dock = DockStyle.Right;
12                     else
13                         uc.Dock = DockStyle.Left;
14                     uc.Value = item;
15                     uc.ForeColor = ForeColor;
16                     uc.LineWidth = m_lineWidth;
17                     this.Controls.Add(uc);
18                     if (RightToLeft == System.Windows.Forms.RightToLeft.Yes)
19                         uc.SendToBack();
20                     else
21                         uc.BringToFront();
22                 }
23             }
24             finally
25             {
26                 ControlHelper.FreezeControl(this, false);
27             }
28         }

完整代码及效果

View Code

View Code

 =======================分割线==========================

下面是日期类控件了,这里偷懒,分成3个控件,分别是日期控件,时间控件,日期时间控件

先说日期控件,

添加一个用户控件UCLEDData

 1 private DateTime m_value;
 2 
 3         [Description("值"), Category("自定义")]
 4         public DateTime Value
 5         {
 6             get { return m_value; }
 7             set
 8             {
 9                 m_value = value;
10                 string str = value.ToString("yyyy-MM-dd");
11                 for (int i = 0; i < str.Length; i++)
12                 {
13                     ((UCLEDNum)this.tableLayoutPanel1.Controls.Find("D" + (i + 1), false)[0]).Value = str[i];
14                 }
15             }
16         }
17 
18         private int m_lineWidth = 8;
19 
20         [Description("线宽度,为了更好的显示效果,请使用偶数"), Category("自定义")]
21         public int LineWidth
22         {
23             get { return m_lineWidth; }
24             set
25             {
26                 m_lineWidth = value;
27                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
28                 {
29                     c.LineWidth = value;
30                 }
31             }
32         }
33 
34         [Description("颜色"), Category("自定义")]
35         public override System.Drawing.Color ForeColor
36         {
37             get
38             {
39                 return base.ForeColor;
40             }
41             set
42             {
43                 base.ForeColor = value;
44                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
45                 {
46                     c.ForeColor = value;
47                 }
48             }
49         }

View Code

View Code

 =======================分割线==========================

添加一个用户控件UCLEDTime

 1  private DateTime m_value;
 2 
 3         [Description("值"), Category("自定义")]
 4         public DateTime Value
 5         {
 6             get { return m_value; }
 7             set
 8             {
 9                 m_value = value;
10                 string str = value.ToString("HH:mm:ss");
11                 for (int i = 0; i < str.Length; i++)
12                 {
13                     ((UCLEDNum)this.tableLayoutPanel1.Controls.Find("D" + (i + 1), false)[0]).Value = str[i];
14                 }
15             }
16         }
17 
18         private int m_lineWidth = 8;
19 
20         [Description("线宽度,为了更好的显示效果,请使用偶数"), Category("自定义")]
21         public int LineWidth
22         {
23             get { return m_lineWidth; }
24             set
25             {
26                 m_lineWidth = value;
27                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
28                 {
29                     c.LineWidth = value;
30                 }
31             }
32         }
33 
34         [Description("颜色"), Category("自定义")]
35         public override System.Drawing.Color ForeColor
36         {
37             get
38             {
39                 return base.ForeColor;
40             }
41             set
42             {
43                 base.ForeColor = value;
44                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
45                 {
46                     c.ForeColor = value;
47                 }
48             }
49         }

View Code

View Code

 =======================分割线==========================

日期时间控件

添加一个用户控件UCLEDDataTime

 1  private DateTime m_value;
 2 
 3         [Description("值"), Category("自定义")]
 4         public DateTime Value
 5         {
 6             get { return m_value; }
 7             set
 8             {
 9                 m_value = value;
10                 string str = value.ToString("yyyy-MM-dd HH:mm:ss");
11                 for (int i = 0; i < str.Length; i++)
12                 {
13                     if (i == 10)
14                         continue;
15                     ((UCLEDNum)this.tableLayoutPanel1.Controls.Find("D" + (i + 1), false)[0]).Value = str[i];
16                 }
17             }
18         }
19 
20         private int m_lineWidth = 8;
21 
22         [Description("线宽度,为了更好的显示效果,请使用偶数"), Category("自定义")]
23         public int LineWidth
24         {
25             get { return m_lineWidth; }
26             set
27             {
28                 m_lineWidth = value;
29                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
30                 {
31                     c.LineWidth = value;
32                 }
33             }
34         }
35 
36         [Description("颜色"), Category("自定义")]
37         public override System.Drawing.Color ForeColor
38         {
39             get
40             {
41                 return base.ForeColor;
42             }
43             set
44             {
45                 base.ForeColor = value;
46                 foreach (UCLEDNum c in this.tableLayoutPanel1.Controls)
47                 {
48                     c.ForeColor = value;
49                 }
50             }
51         }

View Code

View Code

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK