官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
https://www.cnblogs.com/bfyx/p/11364884.html
用处及效果
准备工作
依然用GDI+,请自行百度了解
开始
添加一个类UCArrow,继承UserControl
添加枚举,控制方向
1 /// <summary> 2 /// Enum ArrowDirection 3 /// </summary> 4 public enum ArrowDirection 5 { 6 /// <summary> 7 /// The left 8 /// </summary> 9 Left, 10 /// <summary> 11 /// The right 12 /// </summary> 13 Right, 14 /// <summary> 15 /// The top 16 /// </summary> 17 Top, 18 /// <summary> 19 /// The bottom 20 /// </summary> 21 Bottom, 22 /// <summary> 23 /// The left right 24 /// </summary> 25 Left_Right, 26 /// <summary> 27 /// The top bottom 28 /// </summary> 29 Top_Bottom 30 }
一些属性
1 /// <summary> 2 /// The arrow color 3 /// </summary> 4 private Color arrowColor = Color.FromArgb(255, 77, 59); 5 6 /// <summary> 7 /// Gets or sets the color of the arrow. 8 /// </summary> 9 /// <value>The color of the arrow.</value> 10 [Description("箭头颜色"), Category("自定义")] 11 public Color ArrowColor 12 { 13 get { return arrowColor; } 14 set 15 { 16 arrowColor = value; 17 Refresh(); 18 } 19 } 20 21 /// <summary> 22 /// The border color 23 /// </summary> 24 private Color? borderColor = null; 25 26 /// <summary> 27 /// Gets or sets the color of the border. 28 /// </summary> 29 /// <value>The color of the border.</value> 30 [Description("箭头边框颜色,为空则无边框"), Category("自定义")] 31 public Color? BorderColor 32 { 33 get { return borderColor; } 34 set 35 { 36 borderColor = value; 37 Refresh(); 38 } 39 } 40 41 /// <summary> 42 /// The direction 43 /// </summary> 44 private ArrowDirection direction = ArrowDirection.Right; 45 46 /// <summary> 47 /// Gets or sets the direction. 48 /// </summary> 49 /// <value>The direction.</value> 50 [Description("箭头方向"), Category("自定义")] 51 public ArrowDirection Direction 52 { 53 get { return direction; } 54 set 55 { 56 direction = value; 57 ResetPath(); 58 Refresh(); 59 } 60 } 61 /// <summary> 62 /// 获取或设置控件显示的文字的字体。 63 /// </summary> 64 /// <value>The font.</value> 65 /// <PermissionSet> 66 /// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 67 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 68 /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /> 69 /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 70 /// </PermissionSet> 71 public override Font Font 72 { 73 get 74 { 75 return base.Font; 76 } 77 set 78 { 79 base.Font = value; 80 Refresh(); 81 } 82 } 83 /// <summary> 84 /// 获取或设置控件的前景色。 85 /// </summary> 86 /// <value>The color of the fore.</value> 87 /// <PermissionSet> 88 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 89 /// </PermissionSet> 90 public override Color ForeColor 91 { 92 get 93 { 94 return base.ForeColor; 95 } 96 set 97 { 98 base.ForeColor = value; 99 Refresh(); 100 } 101 } 102 /// <summary> 103 /// The text 104 /// </summary> 105 private string text; 106 /// <summary> 107 /// Gets or sets the text. 108 /// </summary> 109 /// <value>The text.</value> 110 [Bindable(true)] 111 [Browsable(true)] 112 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 113 [EditorBrowsable(EditorBrowsableState.Always)] 114 [Localizable(true)] 115 [Description("箭头文字"), Category("自定义")] 116 public override string Text 117 { 118 get 119 { 120 return text; 121 } 122 set 123 { 124 text = value; 125 Refresh(); 126 } 127 } 128 /// <summary> 129 /// The m path 130 /// </summary> 131 GraphicsPath m_path;
根据方向和大小设置path
1 private void ResetPath() 2 { 3 Point[] ps = null; 4 switch (direction) 5 { 6 case ArrowDirection.Left: 7 ps = new Point[] 8 { 9 new Point(0,this.Height/2), 10 new Point(40,0), 11 new Point(40,this.Height/4), 12 new Point(this.Width-1,this.Height/4), 13 new Point(this.Width-1,this.Height-this.Height/4), 14 new Point(40,this.Height-this.Height/4), 15 new Point(40,this.Height), 16 new Point(0,this.Height/2) 17 }; 18 break; 19 case ArrowDirection.Right: 20 ps = new Point[] 21 { 22 new Point(0,this.Height/4), 23 new Point(this.Width-40,this.Height/4), 24 new Point(this.Width-40,0), 25 new Point(this.Width-1,this.Height/2), 26 new Point(this.Width-40,this.Height), 27 new Point(this.Width-40,this.Height-this.Height/4), 28 new Point(0,this.Height-this.Height/4), 29 new Point(0,this.Height/4) 30 }; 31 break; 32 case ArrowDirection.Top: 33 ps = new Point[] 34 { 35 new Point(this.Width/2,0), 36 new Point(this.Width,40), 37 new Point(this.Width-this.Width/4,40), 38 new Point(this.Width-this.Width/4,this.Height-1), 39 new Point(this.Width/4,this.Height-1), 40 new Point(this.Width/4,40), 41 new Point(0,40), 42 new Point(this.Width/2,0), 43 }; 44 break; 45 case ArrowDirection.Bottom: 46 ps = new Point[] 47 { 48 new Point(this.Width-this.Width/4,0), 49 new Point(this.Width-this.Width/4,this.Height-40), 50 new Point(this.Width,this.Height-40), 51 new Point(this.Width/2,this.Height-1), 52 new Point(0,this.Height-40), 53 new Point(this.Width/4,this.Height-40), 54 new Point(this.Width/4,0), 55 new Point(this.Width-this.Width/4,0), 56 }; 57 break; 58 case ArrowDirection.Left_Right: 59 ps = new Point[] 60 { 61 new Point(0,this.Height/2), 62 new Point(40,0), 63 new Point(40,this.Height/4), 64 new Point(this.Width-40,this.Height/4), 65 new Point(this.Width-40,0), 66 new Point(this.Width-1,this.Height/2), 67 new Point(this.Width-40,this.Height), 68 new Point(this.Width-40,this.Height-this.Height/4), 69 new Point(40,this.Height-this.Height/4), 70 new Point(40,this.Height), 71 new Point(0,this.Height/2), 72 }; 73 break; 74 case ArrowDirection.Top_Bottom: 75 ps = new Point[] 76 { 77 new Point(this.Width/2,0), 78 new Point(this.Width,40), 79 new Point(this.Width-this.Width/4,40), 80 new Point(this.Width-this.Width/4,this.Height-40), 81 new Point(this.Width,this.Height-40), 82 new Point(this.Width/2,this.Height-1), 83 new Point(0,this.Height-40), 84 new Point(this.Width/4,this.Height-40), 85 new Point(this.Width/4,40), 86 new Point(0,40), 87 new Point(this.Width/2,0), 88 }; 89 break; 90 } 91 m_path = new GraphicsPath(); 92 m_path.AddLines(ps); 93 m_path.CloseAllFigures(); 94 }
重绘
1 protected override void OnPaint(PaintEventArgs e) 2 { 3 base.OnPaint(e); 4 var g = e.Graphics; 5 g.SetGDIHigh(); 6 7 g.FillPath(new SolidBrush(arrowColor), m_path); 8 9 if (borderColor != null && borderColor != Color.Empty) 10 g.DrawPath(new Pen(new SolidBrush(borderColor.Value)), m_path); 11 if (!string.IsNullOrEmpty(text)) 12 { 13 var size = g.MeasureString(Text, Font); 14 g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, (this.Height - size.Height) / 2)); 15 } 16 }
完整代码
1 // *********************************************************************** 2 // Assembly : HZH_Controls 3 // Created : 2019-09-10 4 // 5 // *********************************************************************** 6 // <copyright file="UCArrow.cs"> 7 // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com 8 // </copyright> 9 // 10 // Blog: https://www.cnblogs.com/bfyx 11 // GitHub:https://github.com/kwwwvagaa/NetWinformControl 12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 13 // 14 // If you use this code, please keep this note. 15 // *********************************************************************** 16 using System; 17 using System.Collections.Generic; 18 using System.Linq; 19 using System.Text; 20 using System.Windows.Forms; 21 using System.Drawing; 22 using System.Drawing.Drawing2D; 23 using System.ComponentModel; 24 25 namespace HZH_Controls.Controls 26 { 27 /// <summary> 28 /// Class UCArrow. 29 /// Implements the <see cref="System.Windows.Forms.UserControl" /> 30 /// </summary> 31 /// <seealso cref="System.Windows.Forms.UserControl" /> 32 public class UCArrow : UserControl 33 { 34 /// <summary> 35 /// The arrow color 36 /// </summary> 37 private Color arrowColor = Color.FromArgb(255, 77, 59); 38 39 /// <summary> 40 /// Gets or sets the color of the arrow. 41 /// </summary> 42 /// <value>The color of the arrow.</value> 43 [Description("箭头颜色"), Category("自定义")] 44 public Color ArrowColor 45 { 46 get { return arrowColor; } 47 set 48 { 49 arrowColor = value; 50 Refresh(); 51 } 52 } 53 54 /// <summary> 55 /// The border color 56 /// </summary> 57 private Color? borderColor = null; 58 59 /// <summary> 60 /// Gets or sets the color of the border. 61 /// </summary> 62 /// <value>The color of the border.</value> 63 [Description("箭头边框颜色,为空则无边框"), Category("自定义")] 64 public Color? BorderColor 65 { 66 get { return borderColor; } 67 set 68 { 69 borderColor = value; 70 Refresh(); 71 } 72 } 73 74 /// <summary> 75 /// The direction 76 /// </summary> 77 private ArrowDirection direction = ArrowDirection.Right; 78 79 /// <summary> 80 /// Gets or sets the direction. 81 /// </summary> 82 /// <value>The direction.</value> 83 [Description("箭头方向"), Category("自定义")] 84 public ArrowDirection Direction 85 { 86 get { return direction; } 87 set 88 { 89 direction = value; 90 ResetPath(); 91 Refresh(); 92 } 93 } 94 /// <summary> 95 /// 获取或设置控件显示的文字的字体。 96 /// </summary> 97 /// <value>The font.</value> 98 /// <PermissionSet> 99 /// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 100 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 101 /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /> 102 /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 103 /// </PermissionSet> 104 public override Font Font 105 { 106 get 107 { 108 return base.Font; 109 } 110 set 111 { 112 base.Font = value; 113 Refresh(); 114 } 115 } 116 /// <summary> 117 /// 获取或设置控件的前景色。 118 /// </summary> 119 /// <value>The color of the fore.</value> 120 /// <PermissionSet> 121 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 122 /// </PermissionSet> 123 public override Color ForeColor 124 { 125 get 126 { 127 return base.ForeColor; 128 } 129 set 130 { 131 base.ForeColor = value; 132 Refresh(); 133 } 134 } 135 /// <summary> 136 /// The text 137 /// </summary> 138 private string text; 139 /// <summary> 140 /// Gets or sets the text. 141 /// </summary> 142 /// <value>The text.</value> 143 [Bindable(true)] 144 [Browsable(true)] 145 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 146 [EditorBrowsable(EditorBrowsableState.Always)] 147 [Localizable(true)] 148 [Description("箭头文字"), Category("自定义")] 149 public override string Text 150 { 151 get 152 { 153 return text; 154 } 155 set 156 { 157 text = value; 158 Refresh(); 159 } 160 } 161 /// <summary> 162 /// The m path 163 /// </summary> 164 GraphicsPath m_path; 165 /// <summary> 166 /// Initializes a new instance of the <see cref="UCArrow"/> class. 167 /// </summary> 168 public UCArrow() 169 { 170 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 171 this.SetStyle(ControlStyles.DoubleBuffer, true); 172 this.SetStyle(ControlStyles.ResizeRedraw, true); 173 this.SetStyle(ControlStyles.Selectable, true); 174 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 175 this.SetStyle(ControlStyles.UserPaint, true); 176 this.ForeColor = Color.White; 177 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 178 this.SizeChanged += UCArrow_SizeChanged; 179 this.Size = new Size(100, 50); 180 } 181 182 /// <summary> 183 /// Handles the SizeChanged event of the UCArrow control. 184 /// </summary> 185 /// <param name="sender">The source of the event.</param> 186 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> 187 void UCArrow_SizeChanged(object sender, EventArgs e) 188 { 189 ResetPath(); 190 } 191 192 /// <summary> 193 /// Resets the path. 194 /// </summary> 195 private void ResetPath() 196 { 197 Point[] ps = null; 198 switch (direction) 199 { 200 case ArrowDirection.Left: 201 ps = new Point[] 202 { 203 new Point(0,this.Height/2), 204 new Point(40,0), 205 new Point(40,this.Height/4), 206 new Point(this.Width-1,this.Height/4), 207 new Point(this.Width-1,this.Height-this.Height/4), 208 new Point(40,this.Height-this.Height/4), 209 new Point(40,this.Height), 210 new Point(0,this.Height/2) 211 }; 212 break; 213 case ArrowDirection.Right: 214 ps = new Point[] 215 { 216 new Point(0,this.Height/4), 217 new Point(this.Width-40,this.Height/4), 218 new Point(this.Width-40,0), 219 new Point(this.Width-1,this.Height/2), 220 new Point(this.Width-40,this.Height), 221 new Point(this.Width-40,this.Height-this.Height/4), 222 new Point(0,this.Height-this.Height/4), 223 new Point(0,this.Height/4) 224 }; 225 break; 226 case ArrowDirection.Top: 227 ps = new Point[] 228 { 229 new Point(this.Width/2,0), 230 new Point(this.Width,40), 231 new Point(this.Width-this.Width/4,40), 232 new Point(this.Width-this.Width/4,this.Height-1), 233 new Point(this.Width/4,this.Height-1), 234 new Point(this.Width/4,40), 235 new Point(0,40), 236 new Point(this.Width/2,0), 237 }; 238 break; 239 case ArrowDirection.Bottom: 240 ps = new Point[] 241 { 242 new Point(this.Width-this.Width/4,0), 243 new Point(this.Width-this.Width/4,this.Height-40), 244 new Point(this.Width,this.Height-40), 245 new Point(this.Width/2,this.Height-1), 246 new Point(0,this.Height-40), 247 new Point(this.Width/4,this.Height-40), 248 new Point(this.Width/4,0), 249 new Point(this.Width-this.Width/4,0), 250 }; 251 break; 252 case ArrowDirection.Left_Right: 253 ps = new Point[] 254 { 255 new Point(0,this.Height/2), 256 new Point(40,0), 257 new Point(40,this.Height/4), 258 new Point(this.Width-40,this.Height/4), 259 new Point(this.Width-40,0), 260 new Point(this.Width-1,this.Height/2), 261 new Point(this.Width-40,this.Height), 262 new Point(this.Width-40,this.Height-this.Height/4), 263 new Point(40,this.Height-this.Height/4), 264 new Point(40,this.Height), 265 new Point(0,this.Height/2), 266 }; 267 break; 268 case ArrowDirection.Top_Bottom: 269 ps = new Point[] 270 { 271 new Point(this.Width/2,0), 272 new Point(this.Width,40), 273 new Point(this.Width-this.Width/4,40), 274 new Point(this.Width-this.Width/4,this.Height-40), 275 new Point(this.Width,this.Height-40), 276 new Point(this.Width/2,this.Height-1), 277 new Point(0,this.Height-40), 278 new Point(this.Width/4,this.Height-40), 279 new Point(this.Width/4,40), 280 new Point(0,40), 281 new Point(this.Width/2,0), 282 }; 283 break; 284 } 285 m_path = new GraphicsPath(); 286 m_path.AddLines(ps); 287 m_path.CloseAllFigures(); 288 } 289 290 /// <summary> 291 /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。 292 /// </summary> 293 /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param> 294 protected override void OnPaint(PaintEventArgs e) 295 { 296 base.OnPaint(e); 297 var g = e.Graphics; 298 g.SetGDIHigh(); 299 300 g.FillPath(new SolidBrush(arrowColor), m_path); 301 302 if (borderColor != null && borderColor != Color.Empty) 303 g.DrawPath(new Pen(new SolidBrush(borderColor.Value)), m_path); 304 if (!string.IsNullOrEmpty(text)) 305 { 306 var size = g.MeasureString(Text, Font); 307 g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, (this.Height - size.Height) / 2)); 308 } 309 } 310 } 311 312 /// <summary> 313 /// Enum ArrowDirection 314 /// </summary> 315 public enum ArrowDirection 316 { 317 /// <summary> 318 /// The left 319 /// </summary> 320 Left, 321 /// <summary> 322 /// The right 323 /// </summary> 324 Right, 325 /// <summary> 326 /// The top 327 /// </summary> 328 Top, 329 /// <summary> 330 /// The bottom 331 /// </summary> 332 Bottom, 333 /// <summary> 334 /// The left right 335 /// </summary> 336 Left_Right, 337 /// <summary> 338 /// The top bottom 339 /// </summary> 340 Top_Bottom 341 } 342 }
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧