前提

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

开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
<https://gitee.com/kwwwvagaa/net_winform_custom_control>

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

欢迎前来交流探讨: 企鹅群568015492  <https://shang.qq.com/wpa/qunwpa?
idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d>

目录

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

准备工作

GDI+画的,不了解GDI+可以百度了解下先

开始

添加一个用户控件,命名UCCrumbNavigation

提供属性
1 private Color m_navColor = Color.FromArgb(100, 100, 100); 2 3 public
Color NavColor 4 { 5 get { return m_navColor; } 6 set 7 { 8 if (value ==
Color.Empty || value == Color.Transparent) 9 return; 10 m_navColor = value; 11
Refresh();12 } 13 } 14 15 16 private string[] m_navigations = new string[] {
"目录1", "目录2", "目录3" }; 17 GraphicsPath[] m_paths; 18 public string[]
Navigations19 { 20 get { return m_navigations; } 21 set 22 { 23 m_navigations
= value; 24 if (value == null) 25 m_paths = new GraphicsPath[0]; 26 else 27
m_paths =new GraphicsPath[value.Length]; 28 Refresh(); 29 } 30 } 31 32 public
override Font Font 33 { 34 get 35 { 36 return base.Font; 37 } 38 set 39 { 40
base.Font = value; 41 Refresh(); 42 } 43 } 44 45 public override
System.Drawing.Color ForeColor46 { 47 get 48 { 49 return base.ForeColor; 50 }
51 set 52 { 53 base.ForeColor = value; 54 Refresh(); 55 } 56 }
重绘
1 protected override void OnPaint(PaintEventArgs e) 2 { 3 base.OnPaint(e);
4 5 if (m_navigations != null && m_navigations.Length > 0) 6 { 7 var g =
e.Graphics; 8 int intLastX = 0; 9 int intLength = m_navigations.Length; 10 for
(int i = 0; i < m_navigations.Length; i++) 11 { 12 GraphicsPath path = new
GraphicsPath();13 string strText = m_navigations[i]; 14 System.Drawing.SizeF
sizeF = g.MeasureString(strText.Replace(" ", "A"), Font); 15 int intTextWidth =
(int)sizeF.Width + 1; 16 path.AddLine(new Point(intLastX + 1, 1), new
Point(intLastX +1 + (i == 0 ? 0 : 10) + intTextWidth, 1)); 17 18 //if (i !=
(intLength - 1))19 //{ 20 path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 : 10
) + intTextWidth,1), new Point(intLastX + 1 + (i == 0 ? 0 : 10) + intTextWidth +
10, this.Height / 2)); 21 path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 : 10
) + intTextWidth +10, this.Height / 2), new Point(intLastX + 1 + (i == 0 ? 0 :
10) + intTextWidth - 1, this.Height - 1)); 22 //} 23 //else 24 //{ 25 //
path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 : 10) + intTextWidth, 1), new
Point(intLastX + 1 + (i == 0 ? 0 : 10) + intTextWidth, this.Height - 1));26 //}
27 28 path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 : 10) + intTextWidth,
this.Height - 1), new Point(intLastX + 1, this.Height - 1)); 29 30 if (i != 0)
31 { 32 path.AddLine(new Point(intLastX, this.Height - 1), new Point(intLastX +
1 + 10, this.Height / 2)); 33 path.AddLine(new Point(intLastX + 1 + 10, this
.Height /2), new Point(intLastX + 1, 1)); 34 } 35 else 36 { 37 path.AddLine(
new Point(intLastX + 1, this.Height - 1), new Point(intLastX + 1, 1)); 38 } 39
g.FillPath(new SolidBrush(m_navColor), path); 40 41 g.DrawString(strText, this
.Font,new SolidBrush(this.ForeColor), new PointF(intLastX + 2 + (i == 0 ? 0 : 10
), (this.Height - sizeF.Height) / 2 + 1)); 42 m_paths[i] = path; 43 intLastX +=
((i ==0 ? 0 : 10) + intTextWidth + (i == (intLength - 1) ? 0 : 10)); 44 } 45 }
46 47 }
处理一下点击事件
1 void UCCrumbNavigation_MouseDown(object sender, MouseEventArgs e) 2 { 3
if (!DesignMode) 4 { 5 if (m_paths != null && m_paths.Length > 0) 6 { 7
for (int i = 0; i < m_paths.Length; i++) 8 { 9 if
(m_paths[i].IsVisible(e.Location))10 { 11
HZH_Controls.Forms.FrmTips.ShowTipsSuccess(this.FindForm(), m_navigations[i]);
12 } 13 } 14 } 15 } 16 }
完整代码如下
1 using System; 2 using System.Collections.Generic; 3 using
System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using
System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using
System.Drawing.Drawing2D; 10 11 namespace HZH_Controls.Controls 12 { 13
public partial class UCCrumbNavigation : UserControl 14 { 15 private Color
m_navColor = Color.FromArgb(100, 100, 100); 16 17 public Color NavColor 18 {
19 get { return m_navColor; } 20 set 21 { 22 if (value == Color.Empty ||
value == Color.Transparent) 23 return; 24 m_navColor = value; 25 Refresh();
26 } 27 } 28 29 30 private string[] m_navigations = new string[] { "目录1",
"目录2", "目录3" }; 31 GraphicsPath[] m_paths; 32 public string[] Navigations 33
{ 34 get { return m_navigations; } 35 set 36 { 37 m_navigations = value;
38 if (value == null) 39 m_paths = new GraphicsPath[0]; 40 else 41 m_paths =
new GraphicsPath[value.Length]; 42 Refresh(); 43 } 44 } 45 46 public
override Font Font 47 { 48 get 49 { 50 return base.Font; 51 } 52 set
53 { 54 base.Font = value; 55 Refresh(); 56 } 57 } 58 59 public
override System.Drawing.Color ForeColor 60 { 61 get 62 { 63 return base
.ForeColor; 64 } 65 set 66 { 67 base.ForeColor = value; 68 Refresh(); 69
} 70 } 71 72 public UCCrumbNavigation() 73 { 74 InitializeComponent();
75 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 76 this
.SetStyle(ControlStyles.DoubleBuffer,true); 77 this
.SetStyle(ControlStyles.ResizeRedraw,true); 78 this
.SetStyle(ControlStyles.Selectable,true); 79 this
.SetStyle(ControlStyles.SupportsTransparentBackColor,true); 80 this
.SetStyle(ControlStyles.UserPaint,true); 81 this.MouseDown +=
UCCrumbNavigation_MouseDown; 82 } 83 84 void UCCrumbNavigation_MouseDown(
object sender, MouseEventArgs e) 85 { 86 if (!DesignMode) 87 { 88 if
(m_paths !=null && m_paths.Length > 0) 89 { 90 for (int i = 0; i <
m_paths.Length; i++) 91 { 92 if (m_paths[i].IsVisible(e.Location)) 93 { 94
HZH_Controls.Forms.FrmTips.ShowTipsSuccess(this.FindForm(), m_navigations[i]);
95 } 96 } 97 } 98 } 99 } 100 101 protected override void
OnPaint(PaintEventArgs e)102 { 103 base.OnPaint(e); 104 105 if (m_navigations
!=null && m_navigations.Length > 0) 106 { 107 var g = e.Graphics; 108 int
intLastX =0; 109 int intLength = m_navigations.Length; 110 for (int i = 0; i <
m_navigations.Length; i++) 111 { 112 GraphicsPath path = new GraphicsPath();
113 string strText = m_navigations[i]; 114 System.Drawing.SizeF sizeF =
g.MeasureString(strText.Replace(" ", "A"), Font); 115 int intTextWidth = (int
)sizeF.Width +1; 116 path.AddLine(new Point(intLastX + 1, 1), new
Point(intLastX +1 + (i == 0 ? 0 : 10) + intTextWidth, 1)); 117 118 //if (i !=
(intLength - 1))119 //{ 120 path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 :
10) + intTextWidth, 1), new Point(intLastX + 1 + (i == 0 ? 0 : 10) +
intTextWidth +10, this.Height / 2)); 121 path.AddLine(new Point(intLastX + 1 +
(i ==0 ? 0 : 10) + intTextWidth + 10, this.Height / 2), new Point(intLastX + 1
+ (i ==0 ? 0 : 10) + intTextWidth - 1, this.Height - 1)); 122 //} 123 //else 124
//{ 125 // path.AddLine(new Point(intLastX + 1 + (i == 0 ? 0 : 10) +
intTextWidth, 1), new Point(intLastX + 1 + (i == 0 ? 0 : 10) + intTextWidth,
this.Height - 1));126 //} 127 128 path.AddLine(new Point(intLastX + 1 + (i == 0
?0 : 10) + intTextWidth, this.Height - 1), new Point(intLastX + 1, this.Height -
1)); 129 130 if (i != 0) 131 { 132 path.AddLine(new Point(intLastX, this
.Height -1), new Point(intLastX + 1 + 10, this.Height / 2)); 133 path.AddLine(
new Point(intLastX + 1 + 10, this.Height / 2), new Point(intLastX + 1, 1)); 134
}135 else 136 { 137 path.AddLine(new Point(intLastX + 1, this.Height - 1), new
Point(intLastX +1, 1)); 138 } 139 g.FillPath(new SolidBrush(m_navColor),
path);140 141 g.DrawString(strText, this.Font, new SolidBrush(this.ForeColor),
new PointF(intLastX + 2 + (i == 0 ? 0 : 10), (this.Height - sizeF.Height) / 2 +
1)); 142 m_paths[i] = path; 143 intLastX += ((i == 0 ? 0 : 10) + intTextWidth +
(i == (intLength -1) ? 0 : 10)); 144 } 145 } 146 147 } 148 } 149 } View Code
1 namespace HZH_Controls.Controls 2 { 3 partial class UCCrumbNavigation 4 {
5 /// <summary> 6 /// 必需的设计器变量。 7 /// </summary> 8 private
System.ComponentModel.IContainer components =null; 9 10 /// <summary> 11 ///
清理所有正在使用的资源。12 /// </summary> 13 /// <param name="disposing">如果应释放托管资源,为
true;否则为 false。</param> 14 protected override void Dispose(bool disposing) 15 {
16 if (disposing && (components != null)) 17 { 18 components.Dispose(); 19 }
20 base.Dispose(disposing); 21 } 22 23 #region 组件设计器生成的代码 24 25 /// <summary>
26 /// 设计器支持所需的方法 - 不要 27 /// 使用代码编辑器修改此方法的内容。 28 /// </summary> 29 private void
InitializeComponent()30 { 31 this.SuspendLayout(); 32 // 33 //
UCCrumbNavigation34 // 35 this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.None;36 this.Cursor =
System.Windows.Forms.Cursors.Hand;37 this.ForeColor =
System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((
int)(((byte)(224))))); 38 this.MinimumSize = new System.Drawing.Size(0, 25); 39
this.Name = "UCCrumbNavigation"; 40 this.Size = new System.Drawing.Size(220, 25
);41 this.ResumeLayout(false); 42 43 } 44 45 #endregion 46 47 48 } 49 } View
Code
 

用处及效果



最后的话

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