前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
目录
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[] Navigations 19 { 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 ForeColor 46 { 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 }
1 namespace HZH_Controls.Controls 2 { 3 partial class UCCrumbNavigation 4 { 5 ///6 /// 必需的设计器变量。 7 /// 8 private System.ComponentModel.IContainer components = null; 9 10 /// 11 /// 清理所有正在使用的资源。 12 /// 13 /// 如果应释放托管资源,为 true;否则为 false。 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 /// 26 /// 设计器支持所需的方法 - 不要 27 /// 使用代码编辑器修改此方法的内容。 28 /// 29 private void InitializeComponent() 30 { 31 this.SuspendLayout(); 32 // 33 // UCCrumbNavigation 34 // 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 }
用处及效果
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧