官網
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
用處及效果

準備作業
沒什么準備的,就是組裝控制元件
開始
添加一個用戶控制元件UCNavigationMenuOffice
添加屬性
1 /// <summary> 2 /// The main menu height 3 /// </summary> 4 private int mainMenuHeight = 25; 5 6 /// <summary> 7 /// Gets or sets the height of the main menu. 8 /// </summary> 9 /// <value>The height of the main menu.</value> 10 [Description("主選單高度,大于20的值"), Category("自定義")] 11 public int MainMenuHeight 12 { 13 get { return mainMenuHeight; } 14 set 15 { 16 if (value < 20) 17 return; 18 mainMenuHeight = value; 19 this.panMenu.Height = value; 20 } 21 } 22 /// <summary> 23 /// The expand height 24 /// </summary> 25 private int expandHeight = 125; 26 /// <summary> 27 /// Gets or sets the height of the expand. 28 /// </summary> 29 /// <value>The height of the expand.</value> 30 [Description("展開后高度"), Category("自定義")] 31 public int ExpandHeight 32 { 33 get { return expandHeight; } 34 set { expandHeight = value; } 35 } 36 /// <summary> 37 /// The is expand 38 /// </summary> 39 private bool isExpand = true; 40 /// <summary> 41 /// Gets or sets a value indicating whether this instance is expand. 42 /// </summary> 43 /// <value><c>true</c> if this instance is expand; otherwise, <c>false</c>.</value> 44 [Description("是否展開"), Category("自定義")] 45 public bool IsExpand 46 { 47 get { return isExpand; } 48 set 49 { 50 isExpand = value; 51 if (value) 52 { 53 this.Height = expandHeight; 54 ResetChildControl(); 55 } 56 else 57 { 58 this.Height = this.panMenu.Height; 59 this.panChilds.Controls.Clear(); 60 } 61 } 62 } 63 /// <summary> 64 /// Occurs when [click itemed]. 65 /// </summary> 66 [Description("點擊節點事件"), Category("自定義")] 67 68 public event EventHandler ClickItemed; 69 /// <summary> 70 /// The select item 71 /// </summary> 72 private NavigationMenuItemExt selectItem = null; 73 74 /// <summary> 75 /// Gets the select item. 76 /// </summary> 77 /// <value>The select item.</value> 78 [Description("選中的節點"), Category("自定義")] 79 public NavigationMenuItemExt SelectItem 80 { 81 get { return selectItem; } 82 private set { selectItem = value; } 83 } 84 85 /// <summary> 86 /// The items 87 /// </summary> 88 NavigationMenuItemExt[] items; 89 90 /// <summary> 91 /// Gets or sets the items. 92 /// </summary> 93 /// <value>The items.</value> 94 [Description("節點串列"), Category("自定義")] 95 public NavigationMenuItemExt[] Items 96 { 97 get { return items; } 98 set 99 {100 items = value;101 ReloadMenu();102 if (value != null && value.Length > 0)103 {104 selectItem = value[0];105 ResetChildControl();106 }107 }108 }109 /// <summary>110 /// The tip color111 /// </summary>112 private Color tipColor = Color.FromArgb(255, 87, 34);113 114 /// <summary>115 /// Gets or sets the color of the tip.116 /// </summary>117 /// <value>The color of the tip.</value>118 [Description("角標顏色"), Category("自定義")]119 public Color TipColor120 {121 get { return tipColor; }122 set { tipColor = value; }123 }124 125 /// <summary>126 /// 獲取或設定控制元件的前景色,127 /// </summary>128 /// <value>The color of the fore.</value>129 /// <PermissionSet>130 /// <IPermission version="1" Unrestricted="true" />131 /// </PermissionSet>132 public override System.Drawing.Color ForeColor133 {134 get135 {136 return base.ForeColor;137 }138 set139 {140 base.ForeColor = value;141 foreach (Control c in this.Controls)142 {143 c.ForeColor = value;144 }145 }146 }147 /// <summary>148 /// 獲取或設定控制元件顯示的文字的字體,149 /// </summary>150 /// <value>The font.</value>151 /// <PermissionSet>152 /// <IPermission version="1" Unrestricted="true" />153 /// <IPermission version="1" Unrestricted="true" />154 /// <IPermission version="1" Flags="UnmanagedCode, ControlEvidence" />155 /// <IPermission version="1" Unrestricted="true" />156 /// </PermissionSet>157 public override Font Font158 {159 get160 {161 return base.Font;162 }163 set164 {165 base.Font = value;166 foreach (Control c in this.Controls)167 {168 c.Font = value;169 }170 }171 }172 173 /// <summary>174 /// The m LST anchors175 /// </summary>176 Dictionary<NavigationMenuItemExt, FrmAnchor> m_lstAnchors = new Dictionary<NavigationMenuItemExt, FrmAnchor>();
一些事件及輔助函式,處理大小改變時候和重新加載以及滑鼠對應處理
1 /// <summary> 2 /// Handles the SizeChanged event of the UCNavigationMenuOffice control. 3 /// </summary> 4 /// <param name="sender">The source of the event.</param> 5 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> 6 void UCNavigationMenuOffice_SizeChanged(object sender, EventArgs e) 7 { 8 if (isExpand) 9 { 10 expandHeight = this.Height; 11 } 12 } 13 14 /// <summary> 15 /// Resets the child control. 16 /// </summary> 17 public void ResetChildControl() 18 { 19 if (isExpand) 20 { 21 if (selectItem != null) 22 { 23 try 24 { 25 ControlHelper.FreezeControl(this, true); 26 this.panChilds.Controls.Clear(); 27 if (selectItem.ShowControl != null) 28 { 29 HZH_Controls.Controls.UCSplitLine_H split = new UCSplitLine_H(); 30 split.BackColor = Color.FromArgb(50, 197, 197, 197); 31 split.Dock = DockStyle.Top; 32 this.panChilds.Controls.Add(split); 33 split.BringToFront(); 34 this.panChilds.Controls.Add(selectItem.ShowControl); 35 selectItem.ShowControl.Dock = DockStyle.Fill; 36 } 37 } 38 finally 39 { 40 ControlHelper.FreezeControl(this, false); 41 } 42 } 43 } 44 } 45 46 47 /// <summary> 48 /// Reloads the menu. 49 /// </summary> 50 private void ReloadMenu() 51 { 52 try 53 { 54 ControlHelper.FreezeControl(this, true); 55 this.panMenu.Controls.Clear(); 56 if (items != null && items.Length > 0) 57 { 58 foreach (var item in items) 59 { 60 var menu = (NavigationMenuItemExt)item; 61 Label lbl = new Label(); 62 lbl.AutoSize = false; 63 lbl.TextAlign = ContentAlignment.MiddleCenter; 64 lbl.Width = menu.ItemWidth; 65 lbl.Text = menu.Text; 66 67 lbl.Font = Font; 68 lbl.ForeColor = ForeColor; 69 70 lbl.Paint += lbl_Paint; 71 lbl.MouseEnter += lbl_MouseEnter; 72 lbl.Tag = menu; 73 lbl.Click += lbl_Click; 74 lbl.DoubleClick += lbl_DoubleClick; 75 if (menu.AnchorRight) 76 { 77 lbl.Dock = DockStyle.Right; 78 } 79 else 80 { 81 lbl.Dock = DockStyle.Left; 82 } 83 this.panMenu.Controls.Add(lbl); 84 85 lbl.BringToFront(); 86 } 87 } 88 } 89 finally 90 { 91 ControlHelper.FreezeControl(this, false); 92 } 93 } 94 95 /// <summary> 96 /// Handles the DoubleClick event of the lbl control. 97 /// </summary> 98 /// <param name="sender">The source of the event.</param> 99 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>100 void lbl_DoubleClick(object sender, EventArgs e)101 {102 IsExpand = !IsExpand;103 }104 /// <summary>105 /// Handles the Click event of the lbl control.106 /// </summary>107 /// <param name="sender">The source of the event.</param>108 /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>109 void lbl_Click(object sender, EventArgs e)110 {111 Label lbl = sender as Label;112 if (lbl.Tag != null)113 {114 var menu = (NavigationMenuItemExt)lbl.Tag;115 if (menu.ShowControl == null)116 {117 selectItem = menu;118 119 if (ClickItemed != null)120 {121 ClickItemed(this, e);122 }123 }124 else125 {126 if (IsExpand)127 {128 selectItem = menu;129 ResetChildControl();130 }131 }132 }133 }134 /// <summary>135 /// Handles the MouseEnter event of the lbl control.136 /// </summary>137 /// <param name="sender">The source of the event.</param>138 /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>139 void lbl_MouseEnter(object sender, EventArgs e)140 {141 if (!IsExpand)142 {143 Label lbl = sender as Label;144 var menu = lbl.Tag as NavigationMenuItemExt;145 foreach (var item in m_lstAnchors)146 {147 m_lstAnchors[item.Key].Hide();148 }149 if (menu.ShowControl != null)150 {151 if (!m_lstAnchors.ContainsKey(menu))152 {153 m_lstAnchors[menu] = new FrmAnchor(panMenu, menu.ShowControl, isNotFocus: false);154 155 }156 m_lstAnchors[menu].BackColor = this.BackColor;157 m_lstAnchors[menu].Show(this);158 m_lstAnchors[menu].Size = new Size(this.panChilds.Width, expandHeight - mainMenuHeight);159 }160 }161 }162 /// <summary>163 /// Handles the Paint event of the lbl control.164 /// </summary>165 /// <param name="sender">The source of the event.</param>166 /// <param name="e">The <see cref="PaintEventArgs" /> instance containing the event data.</param>167 void lbl_Paint(object sender, PaintEventArgs e)168 {169 Label lbl = sender as Label;170 if (lbl.Tag != null)171 {172 var menu = (NavigationMenuItemExt)lbl.Tag;173 e.Graphics.SetGDIHigh();174 175 if (menu.ShowTip)176 {177 if (!string.IsNullOrEmpty(menu.TipText))178 {179 var rect = new Rectangle(lbl.Width - 25, lbl.Height / 2 - 10, 20, 20);180 var path = rect.CreateRoundedRectanglePath(5);181 e.Graphics.FillPath(new SolidBrush(tipColor), path);182 e.Graphics.DrawString(menu.TipText, new Font("微軟雅黑", 8f), new SolidBrush(Color.White), rect, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });183 }184 else185 {186 e.Graphics.FillEllipse(new SolidBrush(tipColor), new Rectangle(lbl.Width - 20, lbl.Height / 2 - 10, 10, 10));187 }188 }189 if (menu.Icon != null)190 {191 e.Graphics.DrawImage(menu.Icon, new Rectangle(1, (lbl.Height - 25) / 2, 25, 25), 0, 0, menu.Icon.Width, menu.Icon.Height, GraphicsUnit.Pixel);192 }193 }194 }
完整代碼

1 // *********************************************************************** 2 // Assembly : HZH_Controls 3 // Created : 2019-10-12 4 // 5 // *********************************************************************** 6 // <copyright file="UCNavigationMenuOffice.cs"> 7 // Copyright by Huang Zhenghui(黃正輝) All, QQ group:568015492 QQ:623128629 Email:[email protected] 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.ComponentModel; 19 using System.Drawing; 20 using System.Data; 21 using System.Linq; 22 using System.Text; 23 using System.Windows.Forms; 24 using HZH_Controls.Forms; 25 26 namespace HZH_Controls.Controls 27 { 28 /// <summary> 29 /// Class UCNavigationMenuOffice. 30 /// Implements the <see cref="System.Windows.Forms.UserControl" /> 31 /// </summary> 32 /// <seealso cref="System.Windows.Forms.UserControl" /> 33 public partial class UCNavigationMenuOffice : UserControl 34 { 35 /// <summary> 36 /// The main menu height 37 /// </summary> 38 private int mainMenuHeight = 25; 39 40 /// <summary> 41 /// Gets or sets the height of the main menu. 42 /// </summary> 43 /// <value>The height of the main menu.</value> 44 [Description("主選單高度,大于20的值"), Category("自定義")] 45 public int MainMenuHeight 46 { 47 get { return mainMenuHeight; } 48 set 49 { 50 if (value < 20) 51 return; 52 mainMenuHeight = value; 53 this.panMenu.Height = value; 54 } 55 } 56 /// <summary> 57 /// The expand height 58 /// </summary> 59 private int expandHeight = 125; 60 /// <summary> 61 /// Gets or sets the height of the expand. 62 /// </summary> 63 /// <value>The height of the expand.</value> 64 [Description("展開后高度"), Category("自定義")] 65 public int ExpandHeight 66 { 67 get { return expandHeight; } 68 set { expandHeight = value; } 69 } 70 /// <summary> 71 /// The is expand 72 /// </summary> 73 private bool isExpand = true; 74 /// <summary> 75 /// Gets or sets a value indicating whether this instance is expand. 76 /// </summary> 77 /// <value><c>true</c> if this instance is expand; otherwise, <c>false</c>.</value> 78 [Description("是否展開"), Category("自定義")] 79 public bool IsExpand 80 { 81 get { return isExpand; } 82 set 83 { 84 isExpand = value; 85 if (value) 86 { 87 this.Height = expandHeight; 88 ResetChildControl(); 89 } 90 else 91 { 92 this.Height = this.panMenu.Height; 93 this.panChilds.Controls.Clear(); 94 } 95 } 96 } 97 /// <summary> 98 /// Occurs when [click itemed]. 99 /// </summary>100 [Description("點擊節點事件"), Category("自定義")]101 102 public event EventHandler ClickItemed;103 /// <summary>104 /// The select item105 /// </summary>106 private NavigationMenuItemExt selectItem = null;107 108 /// <summary>109 /// Gets the select item.110 /// </summary>111 /// <value>The select item.</value>112 [Description("選中的節點"), Category("自定義")]113 public NavigationMenuItemExt SelectItem114 {115 get { return selectItem; }116 private set { selectItem = value; }117 }118 119 /// <summary>120 /// The items121 /// </summary>122 NavigationMenuItemExt[] items;123 124 /// <summary>125 /// Gets or sets the items.126 /// </summary>127 /// <value>The items.</value>128 [Description("節點串列"), Category("自定義")]129 public NavigationMenuItemExt[] Items130 {131 get { return items; }132 set133 {134 items = value;135 ReloadMenu();136 if (value != null && value.Length > 0)137 {138 selectItem = value[0];139 ResetChildControl();140 }141 }142 }143 /// <summary>144 /// The tip color145 /// </summary>146 private Color tipColor = Color.FromArgb(255, 87, 34);147 148 /// <summary>149 /// Gets or sets the color of the tip.150 /// </summary>151 /// <value>The color of the tip.</value>152 [Description("角標顏色"), Category("自定義")]153 public Color TipColor154 {155 get { return tipColor; }156 set { tipColor = value; }157 }158 159 /// <summary>160 /// 獲取或設定控制元件的前景色,161 /// </summary>162 /// <value>The color of the fore.</value>163 /// <PermissionSet>164 /// <IPermission version="1" Unrestricted="true" />165 /// </PermissionSet>166 public override System.Drawing.Color ForeColor167 {168 get169 {170 return base.ForeColor;171 }172 set173 {174 base.ForeColor = value;175 foreach (Control c in this.Controls)176 {177 c.ForeColor = value;178 }179 }180 }181 /// <summary>182 /// 獲取或設定控制元件顯示的文字的字體,183 /// </summary>184 /// <value>The font.</value>185 /// <PermissionSet>186 /// <IPermission version="1" Unrestricted="true" />187 /// <IPermission version="1" Unrestricted="true" />188 /// <IPermission version="1" Flags="UnmanagedCode, ControlEvidence" />189 /// <IPermission version="1" Unrestricted="true" />190 /// </PermissionSet>191 public override Font Font192 {193 get194 {195 return base.Font;196 }197 set198 {199 base.Font = value;200 foreach (Control c in this.Controls)201 {202 c.Font = value;203 }204 }205 }206 207 /// <summary>208 /// The m LST anchors209 /// </summary>210 Dictionary<NavigationMenuItemExt, FrmAnchor> m_lstAnchors = new Dictionary<NavigationMenuItemExt, FrmAnchor>();211 /// <summary>212 /// Initializes a new instance of the <see cref="UCNavigationMenuOffice"/> class.213 /// </summary>214 public UCNavigationMenuOffice()215 {216 InitializeComponent();217 this.SizeChanged += UCNavigationMenuOffice_SizeChanged;218 items = new NavigationMenuItemExt[0];219 if (ControlHelper.IsDesignMode())220 {221 items = new NavigationMenuItemExt[4];222 for (int i = 0; i < 4; i++)223 {224 items[i] = new NavigationMenuItemExt()225 {226 Text = "選單" + (i + 1),227 AnchorRight = i >= 2228 };229 }230 }231 }232 233 /// <summary>234 /// Handles the SizeChanged event of the UCNavigationMenuOffice control.235 /// </summary>236 /// <param name="sender">The source of the event.</param>237 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>238 void UCNavigationMenuOffice_SizeChanged(object sender, EventArgs e)239 {240 if (isExpand)241 {242 expandHeight = this.Height;243 }244 }245 246 /// <summary>247 /// Resets the child control.248 /// </summary>249 public void ResetChildControl()250 {251 if (isExpand)252 {253 if (selectItem != null)254 {255 try256 {257 ControlHelper.FreezeControl(this, true);258 this.panChilds.Controls.Clear();259 if (selectItem.ShowControl != null)260 {261 HZH_Controls.Controls.UCSplitLine_H split = new UCSplitLine_H();262 split.BackColor = Color.FromArgb(50, 197, 197, 197);263 split.Dock = DockStyle.Top;264 this.panChilds.Controls.Add(split);265 split.BringToFront();266 this.panChilds.Controls.Add(selectItem.ShowControl);267 selectItem.ShowControl.Dock = DockStyle.Fill;268 }269 }270 finally271 {272 ControlHelper.FreezeControl(this, false);273 }274 }275 }276 }277 278 279 /// <summary>280 /// Reloads the menu.281 /// </summary>282 private void ReloadMenu()283 {284 try285 {286 ControlHelper.FreezeControl(this, true);287 this.panMenu.Controls.Clear();288 if (items != null && items.Length > 0)289 {290 foreach (var item in items)291 {292 var menu = (NavigationMenuItemExt)item;293 Label lbl = new Label();294 lbl.AutoSize = false;295 lbl.TextAlign = ContentAlignment.MiddleCenter;296 lbl.Width = menu.ItemWidth;297 lbl.Text = menu.Text;298 299 lbl.Font = Font;300 lbl.ForeColor = ForeColor;301 302 lbl.Paint += lbl_Paint;303 lbl.MouseEnter += lbl_MouseEnter;304 lbl.Tag = menu;305 lbl.Click += lbl_Click;306 lbl.DoubleClick += lbl_DoubleClick;307 if (menu.AnchorRight)308 {309 lbl.Dock = DockStyle.Right;310 }311 else312 {313 lbl.Dock = DockStyle.Left;314 }315 this.panMenu.Controls.Add(lbl);316 317 lbl.BringToFront();318 }319 }320 }321 finally322 {323 ControlHelper.FreezeControl(this, false);324 }325 }326 327 /// <summary>328 /// Handles the DoubleClick event of the lbl control.329 /// </summary>330 /// <param name="sender">The source of the event.</param>331 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>332 void lbl_DoubleClick(object sender, EventArgs e)333 {334 IsExpand = !IsExpand;335 }336 /// <summary>337 /// Handles the Click event of the lbl control.338 /// </summary>339 /// <param name="sender">The source of the event.</param>340 /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>341 void lbl_Click(object sender, EventArgs e)342 {343 Label lbl = sender as Label;344 if (lbl.Tag != null)345 {346 var menu = (NavigationMenuItemExt)lbl.Tag;347 if (menu.ShowControl == null)348 {349 selectItem = menu;350 351 if (ClickItemed != null)352 {353 ClickItemed(this, e);354 }355 }356 else357 {358 if (IsExpand)359 {360 selectItem = menu;361 ResetChildControl();362 }363 }364 }365 }366 /// <summary>367 /// Handles the MouseEnter event of the lbl control.368 /// </summary>369 /// <param name="sender">The source of the event.</param>370 /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>371 void lbl_MouseEnter(object sender, EventArgs e)372 {373 if (!IsExpand)374 {375 Label lbl = sender as Label;376 var menu = lbl.Tag as NavigationMenuItemExt;377 foreach (var item in m_lstAnchors)378 {379 m_lstAnchors[item.Key].Hide();380 }381 if (menu.ShowControl != null)382 {383 if (!m_lstAnchors.ContainsKey(menu))384 {385 m_lstAnchors[menu] = new FrmAnchor(panMenu, menu.ShowControl, isNotFocus: false);386 387 }388 m_lstAnchors[menu].BackColor = this.BackColor;389 m_lstAnchors[menu].Show(this);390 m_lstAnchors[menu].Size = new Size(this.panChilds.Width, expandHeight - mainMenuHeight);391 }392 }393 }394 /// <summary>395 /// Handles the Paint event of the lbl control.396 /// </summary>397 /// <param name="sender">The source of the event.</param>398 /// <param name="e">The <see cref="PaintEventArgs" /> instance containing the event data.</param>399 void lbl_Paint(object sender, PaintEventArgs e)400 {401 Label lbl = sender as Label;402 if (lbl.Tag != null)403 {404 var menu = (NavigationMenuItemExt)lbl.Tag;405 e.Graphics.SetGDIHigh();406 407 if (menu.ShowTip)408 {409 if (!string.IsNullOrEmpty(menu.TipText))410 {411 var rect = new Rectangle(lbl.Width - 25, lbl.Height / 2 - 10, 20, 20);412 var path = rect.CreateRoundedRectanglePath(5);413 e.Graphics.FillPath(new SolidBrush(tipColor), path);414 e.Graphics.DrawString(menu.TipText, new Font("微軟雅黑", 8f), new SolidBrush(Color.White), rect, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });415 }416 else417 {418 e.Graphics.FillEllipse(new SolidBrush(tipColor), new Rectangle(lbl.Width - 20, lbl.Height / 2 - 10, 10, 10));419 }420 }421 if (menu.Icon != null)422 {423 e.Graphics.DrawImage(menu.Icon, new Rectangle(1, (lbl.Height - 25) / 2, 25, 25), 0, 0, menu.Icon.Width, menu.Icon.Height, GraphicsUnit.Pixel);424 }425 }426 }427 }428 }View Code
最后的話
如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星星吧
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/3537.html
標籤:WinForm

