官网

http://www.hzhcontrols.com

前提

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

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

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

欢迎前来交流探讨: 企鹅群568015492 

来都来了,点个【推荐】再走吧,谢谢

NuGet

  1. 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 = ;
  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 < )
  17. return;
  18. mainMenuHeight = value;
  19. this.panMenu.Height = value;
  20. }
  21. }
  22. /// <summary>
  23. /// The expand height
  24. /// </summary>
  25. private int expandHeight = ;
  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 > )
  103. {
  104. selectItem = value[];
  105. ResetChildControl();
  106. }
  107. }
  108. }
  109. /// <summary>
  110. /// The tip color
  111. /// </summary>
  112. private Color tipColor = Color.FromArgb(, , );
  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(, , , );
  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. /// <summary>
  47. /// Reloads the menu.
  48. /// </summary>
  49. private void ReloadMenu()
  50. {
  51. try
  52. {
  53. ControlHelper.FreezeControl(this, true);
  54. this.panMenu.Controls.Clear();
  55. if (items != null && items.Length > )
  56. {
  57. foreach (var item in items)
  58. {
  59. var menu = (NavigationMenuItemExt)item;
  60. Label lbl = new Label();
  61. lbl.AutoSize = false;
  62. lbl.TextAlign = ContentAlignment.MiddleCenter;
  63. lbl.Width = menu.ItemWidth;
  64. lbl.Text = menu.Text;
  65.  
  66. lbl.Font = Font;
  67. lbl.ForeColor = ForeColor;
  68.  
  69. lbl.Paint += lbl_Paint;
  70. lbl.MouseEnter += lbl_MouseEnter;
  71. lbl.Tag = menu;
  72. lbl.Click += lbl_Click;
  73. lbl.DoubleClick += lbl_DoubleClick;
  74. if (menu.AnchorRight)
  75. {
  76. lbl.Dock = DockStyle.Right;
  77. }
  78. else
  79. {
  80. lbl.Dock = DockStyle.Left;
  81. }
  82. this.panMenu.Controls.Add(lbl);
  83.  
  84. lbl.BringToFront();
  85. }
  86. }
  87. }
  88. finally
  89. {
  90. ControlHelper.FreezeControl(this, false);
  91. }
  92. }
  93.  
  94. /// <summary>
  95. /// Handles the DoubleClick event of the lbl control.
  96. /// </summary>
  97. /// <param name="sender">The source of the event.</param>
  98. /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  99. void lbl_DoubleClick(object sender, EventArgs e)
  100. {
  101. IsExpand = !IsExpand;
  102. }
  103. /// <summary>
  104. /// Handles the Click event of the lbl control.
  105. /// </summary>
  106. /// <param name="sender">The source of the event.</param>
  107. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  108. void lbl_Click(object sender, EventArgs e)
  109. {
  110. Label lbl = sender as Label;
  111. if (lbl.Tag != null)
  112. {
  113. var menu = (NavigationMenuItemExt)lbl.Tag;
  114. if (menu.ShowControl == null)
  115. {
  116. selectItem = menu;
  117.  
  118. if (ClickItemed != null)
  119. {
  120. ClickItemed(this, e);
  121. }
  122. }
  123. else
  124. {
  125. if (IsExpand)
  126. {
  127. selectItem = menu;
  128. ResetChildControl();
  129. }
  130. }
  131. }
  132. }
  133. /// <summary>
  134. /// Handles the MouseEnter event of the lbl control.
  135. /// </summary>
  136. /// <param name="sender">The source of the event.</param>
  137. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  138. void lbl_MouseEnter(object sender, EventArgs e)
  139. {
  140. if (!IsExpand)
  141. {
  142. Label lbl = sender as Label;
  143. var menu = lbl.Tag as NavigationMenuItemExt;
  144. foreach (var item in m_lstAnchors)
  145. {
  146. m_lstAnchors[item.Key].Hide();
  147. }
  148. if (menu.ShowControl != null)
  149. {
  150. if (!m_lstAnchors.ContainsKey(menu))
  151. {
  152. m_lstAnchors[menu] = new FrmAnchor(panMenu, menu.ShowControl, isNotFocus: false);
  153.  
  154. }
  155. m_lstAnchors[menu].BackColor = this.BackColor;
  156. m_lstAnchors[menu].Show(this);
  157. m_lstAnchors[menu].Size = new Size(this.panChilds.Width, expandHeight - mainMenuHeight);
  158. }
  159. }
  160. }
  161. /// <summary>
  162. /// Handles the Paint event of the lbl control.
  163. /// </summary>
  164. /// <param name="sender">The source of the event.</param>
  165. /// <param name="e">The <see cref="PaintEventArgs" /> instance containing the event data.</param>
  166. void lbl_Paint(object sender, PaintEventArgs e)
  167. {
  168. Label lbl = sender as Label;
  169. if (lbl.Tag != null)
  170. {
  171. var menu = (NavigationMenuItemExt)lbl.Tag;
  172. e.Graphics.SetGDIHigh();
  173.  
  174. if (menu.ShowTip)
  175. {
  176. if (!string.IsNullOrEmpty(menu.TipText))
  177. {
  178. var rect = new Rectangle(lbl.Width - , lbl.Height / - , , );
  179. var path = rect.CreateRoundedRectanglePath();
  180. e.Graphics.FillPath(new SolidBrush(tipColor), path);
  181. e.Graphics.DrawString(menu.TipText, new Font("微软雅黑", 8f), new SolidBrush(Color.White), rect, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
  182. }
  183. else
  184. {
  185. e.Graphics.FillEllipse(new SolidBrush(tipColor), new Rectangle(lbl.Width - , lbl.Height / - , , ));
  186. }
  187. }
  188. if (menu.Icon != null)
  189. {
  190. e.Graphics.DrawImage(menu.Icon, new Rectangle(, (lbl.Height - ) / , , ), , , menu.Icon.Width, menu.Icon.Height, GraphicsUnit.Pixel);
  191. }
  192. }
  193. }

完整代码

  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: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.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 = ;
  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 < )
  51. return;
  52. mainMenuHeight = value;
  53. this.panMenu.Height = value;
  54. }
  55. }
  56. /// <summary>
  57. /// The expand height
  58. /// </summary>
  59. private int expandHeight = ;
  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 item
  105. /// </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 SelectItem
  114. {
  115. get { return selectItem; }
  116. private set { selectItem = value; }
  117. }
  118.  
  119. /// <summary>
  120. /// The items
  121. /// </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[] Items
  130. {
  131. get { return items; }
  132. set
  133. {
  134. items = value;
  135. ReloadMenu();
  136. if (value != null && value.Length > )
  137. {
  138. selectItem = value[];
  139. ResetChildControl();
  140. }
  141. }
  142. }
  143. /// <summary>
  144. /// The tip color
  145. /// </summary>
  146. private Color tipColor = Color.FromArgb(, , );
  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 TipColor
  154. {
  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 class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  165. /// </PermissionSet>
  166. public override System.Drawing.Color ForeColor
  167. {
  168. get
  169. {
  170. return base.ForeColor;
  171. }
  172. set
  173. {
  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 class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  187. /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  188. /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
  189. /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  190. /// </PermissionSet>
  191. public override Font Font
  192. {
  193. get
  194. {
  195. return base.Font;
  196. }
  197. set
  198. {
  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 anchors
  209. /// </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[];
  219. if (ControlHelper.IsDesignMode())
  220. {
  221. items = new NavigationMenuItemExt[];
  222. for (int i = ; i < ; i++)
  223. {
  224. items[i] = new NavigationMenuItemExt()
  225. {
  226. Text = "菜单" + (i + ),
  227. AnchorRight = i >=
  228. };
  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. try
  256. {
  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(, , , );
  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. finally
  271. {
  272. ControlHelper.FreezeControl(this, false);
  273. }
  274. }
  275. }
  276. }
  277.  
  278. /// <summary>
  279. /// Reloads the menu.
  280. /// </summary>
  281. private void ReloadMenu()
  282. {
  283. try
  284. {
  285. ControlHelper.FreezeControl(this, true);
  286. this.panMenu.Controls.Clear();
  287. if (items != null && items.Length > )
  288. {
  289. foreach (var item in items)
  290. {
  291. var menu = (NavigationMenuItemExt)item;
  292. Label lbl = new Label();
  293. lbl.AutoSize = false;
  294. lbl.TextAlign = ContentAlignment.MiddleCenter;
  295. lbl.Width = menu.ItemWidth;
  296. lbl.Text = menu.Text;
  297.  
  298. lbl.Font = Font;
  299. lbl.ForeColor = ForeColor;
  300.  
  301. lbl.Paint += lbl_Paint;
  302. lbl.MouseEnter += lbl_MouseEnter;
  303. lbl.Tag = menu;
  304. lbl.Click += lbl_Click;
  305. lbl.DoubleClick += lbl_DoubleClick;
  306. if (menu.AnchorRight)
  307. {
  308. lbl.Dock = DockStyle.Right;
  309. }
  310. else
  311. {
  312. lbl.Dock = DockStyle.Left;
  313. }
  314. this.panMenu.Controls.Add(lbl);
  315.  
  316. lbl.BringToFront();
  317. }
  318. }
  319. }
  320. finally
  321. {
  322. ControlHelper.FreezeControl(this, false);
  323. }
  324. }
  325.  
  326. /// <summary>
  327. /// Handles the DoubleClick event of the lbl control.
  328. /// </summary>
  329. /// <param name="sender">The source of the event.</param>
  330. /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  331. void lbl_DoubleClick(object sender, EventArgs e)
  332. {
  333. IsExpand = !IsExpand;
  334. }
  335. /// <summary>
  336. /// Handles the Click event of the lbl control.
  337. /// </summary>
  338. /// <param name="sender">The source of the event.</param>
  339. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  340. void lbl_Click(object sender, EventArgs e)
  341. {
  342. Label lbl = sender as Label;
  343. if (lbl.Tag != null)
  344. {
  345. var menu = (NavigationMenuItemExt)lbl.Tag;
  346. if (menu.ShowControl == null)
  347. {
  348. selectItem = menu;
  349.  
  350. if (ClickItemed != null)
  351. {
  352. ClickItemed(this, e);
  353. }
  354. }
  355. else
  356. {
  357. if (IsExpand)
  358. {
  359. selectItem = menu;
  360. ResetChildControl();
  361. }
  362. }
  363. }
  364. }
  365. /// <summary>
  366. /// Handles the MouseEnter event of the lbl control.
  367. /// </summary>
  368. /// <param name="sender">The source of the event.</param>
  369. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  370. void lbl_MouseEnter(object sender, EventArgs e)
  371. {
  372. if (!IsExpand)
  373. {
  374. Label lbl = sender as Label;
  375. var menu = lbl.Tag as NavigationMenuItemExt;
  376. foreach (var item in m_lstAnchors)
  377. {
  378. m_lstAnchors[item.Key].Hide();
  379. }
  380. if (menu.ShowControl != null)
  381. {
  382. if (!m_lstAnchors.ContainsKey(menu))
  383. {
  384. m_lstAnchors[menu] = new FrmAnchor(panMenu, menu.ShowControl, isNotFocus: false);
  385.  
  386. }
  387. m_lstAnchors[menu].BackColor = this.BackColor;
  388. m_lstAnchors[menu].Show(this);
  389. m_lstAnchors[menu].Size = new Size(this.panChilds.Width, expandHeight - mainMenuHeight);
  390. }
  391. }
  392. }
  393. /// <summary>
  394. /// Handles the Paint event of the lbl control.
  395. /// </summary>
  396. /// <param name="sender">The source of the event.</param>
  397. /// <param name="e">The <see cref="PaintEventArgs" /> instance containing the event data.</param>
  398. void lbl_Paint(object sender, PaintEventArgs e)
  399. {
  400. Label lbl = sender as Label;
  401. if (lbl.Tag != null)
  402. {
  403. var menu = (NavigationMenuItemExt)lbl.Tag;
  404. e.Graphics.SetGDIHigh();
  405.  
  406. if (menu.ShowTip)
  407. {
  408. if (!string.IsNullOrEmpty(menu.TipText))
  409. {
  410. var rect = new Rectangle(lbl.Width - , lbl.Height / - , , );
  411. var path = rect.CreateRoundedRectanglePath();
  412. e.Graphics.FillPath(new SolidBrush(tipColor), path);
  413. e.Graphics.DrawString(menu.TipText, new Font("微软雅黑", 8f), new SolidBrush(Color.White), rect, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
  414. }
  415. else
  416. {
  417. e.Graphics.FillEllipse(new SolidBrush(tipColor), new Rectangle(lbl.Width - , lbl.Height / - , , ));
  418. }
  419. }
  420. if (menu.Icon != null)
  421. {
  422. e.Graphics.DrawImage(menu.Icon, new Rectangle(, (lbl.Height - ) / , , ), , , menu.Icon.Width, menu.Icon.Height, GraphicsUnit.Pixel);
  423. }
  424. }
  425. }
  426. }
  427. }

最后的话

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

(八十四)c#Winform自定义控件-导航菜单(类Office菜单)的更多相关文章

  1. (八十三)c#Winform自定义控件-导航菜单(扩展)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  2. (八十)c#Winform自定义控件-分割线标签-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  3. 第三百八十四节,Django+Xadmin打造上线标准的在线教育平台—路由映射与静态文件配置以及会员注册

    第三百八十四节,Django+Xadmin打造上线标准的在线教育平台—路由映射与静态文件配置以及会员注册 基于类的路由映射 from django.conf.urls import url, incl ...

  4. “全栈2019”Java第八十四章:接口中嵌套接口详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 孤荷凌寒自学python第八十四天搭建jTessBoxEditor来训练tesseract模块

    孤荷凌寒自学python第八十四天搭建jTessBoxEditor来训练tesseract模块 (完整学习过程屏幕记录视频地址在文末) 由于本身tesseract模块针对普通的验证码图片的识别率并不高 ...

  6. 《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程)

    1.简介 TestNG还为我们提供了测试的记录功能-日志.例如,在运行测试用例期间,用户希望在控制台中记录一些信息.信息可以是任何细节取决于目的.牢记我们正在使用Selenium进行测试,我们需要有助 ...

  7. (七十九)c#Winform自定义控件-导航菜单

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  8. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  9. (二十)c#Winform自定义控件-有后退的窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  10. (五十)c#Winform自定义控件-滑块

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

随机推荐

  1. PAT L3-017. 森森快递

    L3-017. 森森快递 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 俞勇(上海交通大学) 森森开了一家快递公司,叫森森快递.因为 ...

  2. Redis哨兵(Sentinel)模式快速入门

    更多内容,欢迎关注微信公众号:全菜工程师小辉.公众号回复关键词,领取免费学习资料. 当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用. ...

  3. FreeSql (十五)查询数据

    FreeSql在查询数据下足了功能,链式查询语法.多表查询.表达式函数支持得非常到位. IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnect ...

  4. 原创 | 手摸手带您学会 Elasticsearch 单机、集群、插件安装(图文教程)

    欢迎关注笔者的公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site/ ...

  5. valueForKey与valueForKeyPath 区别

    1.删除数组中重复的数据 2.valueForKeyPath:可以深层次取到子属性,不管隐藏的多深  valueForKey:无法取到深层次子属性 但是也有其相似的地方: 比如:快速找到字典数组中ke ...

  6. 使用Bookinfo应用测试Kuma服务网格

    最近,开源API管理平台Kong服务供应商近日放出了新的开源项目Kuma.本文尝试将 bookinfo 应用部署在 Kuma 网格中,以便帮助大家更好的理解 Kuma 项目.   Kuma是能用于管理 ...

  7. query 与 params 使用

    这个是路由: {     path:'/city/:city',     name:'City',     component:City   }   下面使用query和params分别传参 quer ...

  8. 01 (H5*) Vue第一天

    目录 1:什么是Vue.js 2:MVC和MVVM. 3:为什么要学习前段框架 4:框架和库的区别 5:怎么使用Vue. 6:常见的Vue指令 7:  五大事件修饰符 8:在vue中使用class样式 ...

  9. DataGuard开启failover

    1.修改保护模式 DGMGRL> edit configuration set protection mode as maxAvailability; Succeeded. 2.修改日志同步方式 ...

  10. 给idea设置默认使用的JDK

    一,前言 在文章给idea设置默认使用的maven配置中我给我的idea设置了默认使用的maven,并且在setting.xml文件中,设置了本地的maven仓库,这样就不会使用maven默认在C盘的 ...