前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
前提
入行已經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
用處及效果
準備工作
沒什麼準備的,就是組裝控制項
開始
添加一個用戶控制項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 color 111 /// </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 TipColor 120 { 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 class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 131 /// </PermissionSet> 132 public override System.Drawing.Color ForeColor 133 { 134 get 135 { 136 return base.ForeColor; 137 } 138 set 139 { 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 class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 153 /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 154 /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /> 155 /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 156 /// </PermissionSet> 157 public override Font Font 158 { 159 get 160 { 161 return base.Font; 162 } 163 set 164 { 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 anchors 175 /// </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 else 125 { 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 else 185 { 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 }
完整代碼
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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