前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 如果觉得写的还行,请点个 star 支持一下吧 欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492 麻烦博客下方点个【推荐】,谢谢 NuGet Install-Package HZH_Controls 目录 https://www.cnblogs.com/bfyx/p/11364884.html 用处及效果 准备工作 依然是GDI+ 不了解请先百度一下 开始 添加一个类UCBottle,继承UserControl 添加几个控制属性 复制代码 1 //瓶身区域 2 /// 3 /// The m working rect 4 /// 5 Rectangle m_workingRect; 6 7 /// 8 /// The title 9 /// 10 string title = "瓶子1"; 11 12 /// 13 /// Gets or sets the title. 14 /// 15 /// The title. 16 [Description("标题"), Category("自定义")] 17 public string Title 18 { 19 get { return title; } 20 set 21 { 22 title = value; 23 ResetWorkingRect(); 24 Refresh(); 25 } 26 } 27 28 /// 29 /// The bottle color 30 /// 31 private Color bottleColor = Color.FromArgb(255, 77, 59); 32 33 /// 34 /// Gets or sets the color of the bottle. 35 /// 36 /// The color of the bottle. 37 [Description("瓶子颜色"), Category("自定义")] 38 public Color BottleColor 39 { 40 get { return bottleColor; } 41 set 42 { 43 bottleColor = value; 44 Refresh(); 45 } 46 } 47 48 /// 49 /// The bottle mouth color 50 /// 51 private Color bottleMouthColor = Color.FromArgb(105, 105, 105); 52 53 /// 54 /// Gets or sets the color of the bottle mouth. 55 /// 56 /// The color of the bottle mouth. 57 [Description("瓶口颜色"), Category("自定义")] 58 public Color BottleMouthColor 59 { 60 get { return bottleMouthColor; } 61 set { bottleMouthColor = value; } 62 } 63 64 /// 65 /// The liquid color 66 /// 67 private Color liquidColor = Color.FromArgb(3, 169, 243); 68 69 /// 70 /// Gets or sets the color of the liquid. 71 /// 72 /// The color of the liquid. 73 [Description("液体颜色"), Category("自定义")] 74 public Color LiquidColor 75 { 76 get { return liquidColor; } 77 set 78 { 79 liquidColor = value; 80 Refresh(); 81 } 82 } 83 84 85 /// 86 /// 获取或设置控件显示的文字的字体。 87 /// 88 /// The font. 89 /// 90 /// 91 /// 92 /// 93 /// 94 /// 95 [Description("文字字体"), Category("自定义")] 96 public override Font Font 97 { 98 get 99 { 100 return base.Font; 101 } 102 set 103 { 104 base.Font = value; 105 ResetWorkingRect(); 106 Refresh(); 107 } 108 } 109 110 /// 111 /// 获取或设置控件的前景色。 112 /// 113 /// The color of the fore. 114 /// 115 /// 116 /// 117 [Description("文字颜色"), Category("自定义")] 118 public override System.Drawing.Color ForeColor 119 { 120 get 121 { 122 return base.ForeColor; 123 } 124 set 125 { 126 base.ForeColor = value; 127 Refresh(); 128 } 129 } 130 131 /// 132 /// The maximum value 133 /// 134 private decimal maxValue = 100; 135 136 /// 137 /// Gets or sets the maximum value. 138 /// 139 /// The maximum value. 140 [Description("最大值"), Category("自定义")] 141 public decimal MaxValue 142 { 143 get { return maxValue; } 144 set 145 { 146 if (value < m_value) 147 return; 148 maxValue = value; 149 Refresh(); 150 } 151 } 152 153 /// 154 /// The m value 155 /// 156 private decimal m_value = 50; 157 158 /// 159 /// Gets or sets the value. 160 /// 161 /// The value. 162 [Description("值"), Category("自定义")] 163 public decimal Value 164 { 165 get { return m_value; } 166 set 167 { 168 if (value <= 0 || value > maxValue) 169 return; 170 m_value = value; 171 Refresh(); 172 } 173 } 174 175 /// 176 /// The m no 177 /// 178 private string m_NO; 179 /// 180 /// Gets or sets the NO. 181 /// 182 /// The no. 183 [Description("编号"), Category("自定义")] 184 public string NO 185 { 186 get { return m_NO; } 187 set 188 { 189 m_NO = value; 190 Refresh(); 191 } 192 } 复制代码 重绘 复制代码 1 protected override void OnPaint(PaintEventArgs e) 2 { 3 base.OnPaint(e); 4 var g = e.Graphics; 5 g.SetGDIHigh(); 6 //写文字 7 var size = g.MeasureString(title, Font); 8 g.DrawString(title, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, 2)); 9 10 //画空瓶子 11 GraphicsPath pathPS = new GraphicsPath(); 12 Point[] psPS = new Point[] 13 { 14 new Point(m_workingRect.Left, m_workingRect.Top), 15 new Point(m_workingRect.Right - 1, m_workingRect.Top), 16 new Point(m_workingRect.Right - 1, m_workingRect.Bottom - 15), 17 new Point(m_workingRect.Right - 1 - m_workingRect.Width / 4, m_workingRect.Bottom), 18 new Point(m_workingRect.Left + m_workingRect.Width / 4, m_workingRect.Bottom), 19 new Point(m_workingRect.Left, m_workingRect.Bottom - 15), 20 }; 21 pathPS.AddLines(psPS); 22 pathPS.CloseAllFigures(); 23 g.FillPath(new SolidBrush(bottleColor), pathPS); 24 //画液体 25 decimal decYTHeight = (m_value / maxValue) * m_workingRect.Height; 26 GraphicsPath pathYT = new GraphicsPath(); 27 Rectangle rectYT = Rectangle.Empty; 28 if (decYTHeight < 15) 29 { 30 PointF[] psYT = new PointF[] 31 { 32 new PointF((float)(m_workingRect.Left+(15-decYTHeight))+3,(float)(m_workingRect.Bottom-decYTHeight)), 33 new PointF((float)(m_workingRect.Right-(15-decYTHeight))-3,(float)(m_workingRect.Bottom-decYTHeight)), 34 new PointF(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom), 35 new PointF(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom), 36 }; 37 pathYT.AddLines(psYT); 38 pathYT.CloseAllFigures(); 39 rectYT = new Rectangle((m_workingRect.Left + (15 - (int)decYTHeight)) + 3, m_workingRect.Bottom - (int)decYTHeight - 5, m_workingRect.Width - (int)(15 - decYTHeight) * 2 - 8, 10); 40 } 41 else 42 { 43 PointF[] psYT = new PointF[] 44 { 45 new PointF(m_workingRect.Left,(float)(m_workingRect.Bottom-decYTHeight)), 46 new PointF(m_workingRect.Right-1,(float)(m_workingRect.Bottom-decYTHeight)), 47 new PointF(m_workingRect.Right-1,m_workingRect.Bottom-15), 48 new PointF(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom), 49 new PointF(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom), 50 new PointF(m_workingRect.Left,m_workingRect.Bottom-15), 51 }; 52 pathYT.AddLines(psYT); 53 pathYT.CloseAllFigures(); 54 rectYT = new Rectangle(m_workingRect.Left, m_workingRect.Bottom - (int)decYTHeight - 5, m_workingRect.Width, 10); 55 } 56 57 g.FillPath(new SolidBrush(liquidColor), pathYT); 58 g.FillPath(new SolidBrush(Color.FromArgb(50, bottleMouthColor)), pathYT); 59 //画液体面 60 g.FillEllipse(new SolidBrush(liquidColor), rectYT); 61 g.FillEllipse(new SolidBrush(Color.FromArgb(50, Color.White)), rectYT); 62 63 //画高亮 64 int intCount = m_workingRect.Width / 2 / 4; 65 int intSplit = (255 - 100) / intCount; 66 for (int i = 0; i < intCount; i++) 67 { 68 int _penWidth = m_workingRect.Width / 2 - 4 * i; 69 if (_penWidth <= 0) 70 _penWidth = 1; 71 g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(10, Color.White)), _penWidth), new Point(m_workingRect.Width / 2, m_workingRect.Top), new Point(m_workingRect.Width / 2, m_workingRect.Bottom - 15)); 72 if (_penWidth == 1) 73 break; 74 } 75 76 //画瓶底 77 g.FillEllipse(new SolidBrush(bottleColor), new RectangleF(m_workingRect.Left, m_workingRect.Top - 5, m_workingRect.Width - 2, 10)); 78 g.FillEllipse(new SolidBrush(Color.FromArgb(50, Color.White)), new RectangleF(m_workingRect.Left, m_workingRect.Top - 5, m_workingRect.Width - 2, 10)); 79 //画瓶口 80 g.FillRectangle(new SolidBrush(bottleMouthColor), new Rectangle(m_workingRect.Left + m_workingRect.Width / 4, m_workingRect.Bottom, m_workingRect.Width / 2, 15)); 81 //画瓶颈阴影 82 GraphicsPath pathPJ = new GraphicsPath(); 83 Point[] psPJ = new Point[] 84 { 85 new Point(m_workingRect.Left, m_workingRect.Bottom-15), 86 new Point(m_workingRect.Right-1, m_workingRect.Bottom-15), 87 new Point(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom), 88 new Point(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom) 89 }; 90 pathPJ.AddLines(psPJ); 91 pathPJ.CloseAllFigures(); 92 g.FillPath(new SolidBrush(Color.FromArgb(50, bottleMouthColor)), pathPJ); 93 94 //写编号 95 if (!string.IsNullOrEmpty(m_NO)) 96 { 97 var nosize = g.MeasureString(m_NO, Font); 98 g.DrawString(m_NO, Font, new SolidBrush(ForeColor), new PointF((this.Width - nosize.Width) / 2, m_workingRect.Top + 10)); 99 } 100 } 复制代码 代码就这么多 完整代码 View Code 最后的话 如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧 作者:冰封一夏 出处:http://www.cnblogs.com/bfyx/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。https://www.cnblogs.com/bfyx/p/11463252.html