前提

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

github:https://github.com/kwwwvagaa/netwinformcontrol

码云:

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

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

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

nuget

install-package hzh_controls

目录

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

用处及效果

以上为demo效果,你使用此控件可以实现以下弹出效果

 

 

准备工作

没什么准备的

开始

添加一个类navigationmenuitemext 继承navigationmenuitembase

1     public class navigationmenuitemext : navigationmenuitembase
2     {
3         public system.windows.forms.control showcontrol { get; set; }
4     }

添加一个用户控件ucnavigationmenuext

添加属性

  1 /// <summary>
  2         /// occurs when [click itemed].
  3         /// </summary>
  4         [description("点击节点事件"), category("自定义")]
  5 
  6         public event eventhandler clickitemed;
  7         /// <summary>
  8         /// the select item
  9         /// </summary>
 10         private navigationmenuitemext selectitem = null;
 11 
 12         /// <summary>
 13         /// gets the select item.
 14         /// </summary>
 15         /// <value>the select item.</value>
 16         [description("选中的节点"), category("自定义")]
 17         public navigationmenuitemext selectitem
 18         {
 19             get { return selectitem; }
 20             private set { selectitem = value; }
 21         }
 22 
 23         /// <summary>
 24         /// the items
 25         /// </summary>
 26         navigationmenuitemext[] items;
 27 
 28         /// <summary>
 29         /// gets or sets the items.
 30         /// </summary>
 31         /// <value>the items.</value>
 32         [description("节点列表"), category("自定义")]
 33         public navigationmenuitemext[] items
 34         {
 35             get { return items; }
 36             set
 37             {
 38                 items = value;
 39                 reloadmenu();
 40             }
 41         }
 42         /// <summary>
 43         /// the tip color
 44         /// </summary>
 45         private color tipcolor = color.fromargb(255, 87, 34);
 46 
 47         /// <summary>
 48         /// gets or sets the color of the tip.
 49         /// </summary>
 50         /// <value>the color of the tip.</value>
 51         [description("角标颜色"), category("自定义")]
 52         public color tipcolor
 53         {
 54             get { return tipcolor; }
 55             set { tipcolor = value; }
 56         }
 57 
 58         /// <summary>
 59         /// 获取或设置控件的前景色。
 60         /// </summary>
 61         /// <value>the color of the fore.</value>
 62         /// <permissionset>
 63         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 64         /// </permissionset>
 65         public override system.drawing.color forecolor
 66         {
 67             get
 68             {
 69                 return base.forecolor;
 70             }
 71             set
 72             {
 73                 base.forecolor = value;
 74                 foreach (control c in this.controls)
 75                 {
 76                     c.forecolor = value;
 77                 }
 78             }
 79         }
 80         /// <summary>
 81         /// 获取或设置控件显示的文字的字体。
 82         /// </summary>
 83         /// <value>the font.</value>
 84         /// <permissionset>
 85         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 86         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 87         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
 88         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 89         /// </permissionset>
 90         public override font font
 91         {
 92             get
 93             {
 94                 return base.font;
 95             }
 96             set
 97             {
 98                 base.font = value;
 99                 foreach (control c in this.controls)
100                 {
101                     c.font = value;
102                 }
103             }
104         }
105 
106         /// <summary>
107         /// the m lst anchors
108         /// </summary>
109         dictionary<navigationmenuitemext, frmanchor> m_lstanchors = new dictionary<navigationmenuitemext, frmanchor>();

加载和绘图

  1  private void reloadmenu()
  2         {
  3             try
  4             {
  5                 controlhelper.freezecontrol(this, true);
  6                 this.controls.clear();
  7                 if (items != null && items.length > 0)
  8                 {
  9                     foreach (var item in items)
 10                     {
 11                         var menu = (navigationmenuitemext)item;
 12                         label lbl = new label();
 13                         lbl.autosize = false;
 14                         lbl.textalign = contentalignment.middlecenter;
 15                         lbl.width = menu.itemwidth;
 16                         lbl.text = menu.text;
 17 
 18                         lbl.font = font;
 19                         lbl.forecolor = forecolor;
 20 
 21                         lbl.paint += lbl_paint;
 22                         lbl.mouseenter += lbl_mouseenter;                    
 23                         lbl.tag = menu;
 24                         lbl.click += lbl_click;
 25                         if (menu.anchorright)
 26                         {
 27                             lbl.dock = dockstyle.right;
 28                         }
 29                         else
 30                         {
 31                             lbl.dock = dockstyle.left;
 32                         }
 33                         this.controls.add(lbl);
 34 
 35                         lbl.bringtofront();
 36                     }
 37 
 38 
 39                 }
 40             }
 41             finally
 42             {
 43                 controlhelper.freezecontrol(this, false);
 44             }
 45         }
 46 
 47         /// <summary>
 48         /// handles the click event of the lbl control.
 49         /// </summary>
 50         /// <param name="sender">the source of the event.</param>
 51         /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param>
 52         void lbl_click(object sender, eventargs e)
 53         {
 54             label lbl = sender as label;
 55             if (lbl.tag != null)
 56             {
 57                 var menu = (navigationmenuitemext)lbl.tag;
 58                 if (menu.showcontrol == null)
 59                 {
 60                     selectitem = menu;
 61 
 62                     while (m_lstanchors.count > 0)
 63                     {
 64                         try
 65                         {
 66                             foreach (var item in m_lstanchors)
 67                             {
 68                                 item.value.hide();
 69                             }
 70                         }
 71                         catch { }
 72                     }
 73 
 74                     if (clickitemed != null)
 75                     {
 76                         clickitemed(this, e);
 77                     }
 78                 }               
 79             }
 80         }
 81         /// <summary>
 82         /// handles the mouseenter event of the lbl control.
 83         /// </summary>
 84         /// <param name="sender">the source of the event.</param>
 85         /// <param name="e">the <see cref="eventargs" /> instance containing the event data.</param>
 86         void lbl_mouseenter(object sender, eventargs e)
 87         {
 88             label lbl = sender as label;
 89             var menu = lbl.tag as navigationmenuitemext;
 90             foreach (var item in m_lstanchors)
 91             {
 92                 m_lstanchors[item.key].hide();
 93             }
 94             if (menu.showcontrol != null)
 95             {
 96                 if (!m_lstanchors.containskey(menu))
 97                 {
 98                     m_lstanchors[menu] = new frmanchor(lbl, menu.showcontrol);
 99                 }
100                 m_lstanchors[menu].show();
101                 m_lstanchors[menu].size = menu.showcontrol.size;
102             }
103         }
104         /// <summary>
105         /// handles the paint event of the lbl control.
106         /// </summary>
107         /// <param name="sender">the source of the event.</param>
108         /// <param name="e">the <see cref="painteventargs" /> instance containing the event data.</param>
109         void lbl_paint(object sender, painteventargs e)
110         {
111             label lbl = sender as label;
112             if (lbl.tag != null)
113             {
114                 var menu = (navigationmenuitemext)lbl.tag;
115                 e.graphics.setgdihigh();
116 
117                 if (menu.showtip)
118                 {
119                     if (!string.isnullorempty(menu.tiptext))
120                     {
121                         var rect = new rectangle(lbl.width - 25, lbl.height / 2 - 10, 20, 20);
122                         var path = rect.createroundedrectanglepath(5);
123                         e.graphics.fillpath(new solidbrush(tipcolor), path);
124                         e.graphics.drawstring(menu.tiptext, new font("微软雅黑", 8f), new solidbrush(color.white), rect, new stringformat() { alignment = stringalignment.center, linealignment = stringalignment.center });
125                     }
126                     else
127                     {
128                         e.graphics.fillellipse(new solidbrush(tipcolor), new rectangle(lbl.width - 20, lbl.height / 2 - 10, 10, 10));
129                     }
130                 }
131                 if (menu.icon != null)
132                 {
133                     e.graphics.drawimage(menu.icon, new rectangle(1, (lbl.height - 25) / 2, 25, 25), 0, 0, menu.icon.width, menu.icon.height, graphicsunit.pixel);
134                 }
135             }
136         }

全部代码

  1 // ***********************************************************************
2 // assembly         : hzh_controls
3 // created          : 2019-10-11
4 //
5 // ***********************************************************************
6 // <copyright file="ucnavigationmenuext.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 ucnavigationmenuext.
30     /// implements the <see cref="system.windows.forms.usercontrol" />
31     /// </summary>
32     /// <seealso cref="system.windows.forms.usercontrol" />
33     [defaultevent("clickitemed")]
34     public partial class ucnavigationmenuext : usercontrol
35     {
36         /// <summary>
37         /// occurs when [click itemed].
38         /// </summary>
39         [description("点击节点事件"), category("自定义")]
40 
41         public event eventhandler clickitemed;
42         /// <summary>
43         /// the select item
44         /// </summary>
45         private navigationmenuitemext selectitem = null;
46 
47         /// <summary>
48         /// gets the select item.
49         /// </summary>
50         /// <value>the select item.</value>
51         [description("选中的节点"), category("自定义")]
52         public navigationmenuitemext selectitem
53         {
54             get { return selectitem; }
55             private set { selectitem = value; }
56         }
57 
58         /// <summary>
59         /// the items
60         /// </summary>
61         navigationmenuitemext[] items;
62 
63         /// <summary>
64         /// gets or sets the items.
65         /// </summary>
66         /// <value>the items.</value>
67         [description("节点列表"), category("自定义")]
68         public navigationmenuitemext[] items
69         {
70             get { return items; }
71             set
72             {
73                 items = value;
74                 reloadmenu();
75             }
76         }
77         /// <summary>
78         /// the tip color
79         /// </summary>
80         private color tipcolor = color.fromargb(255, 87, 34);
81 
82         /// <summary>
83         /// gets or sets the color of the tip.
84         /// </summary>
85         /// <value>the color of the tip.</value>
86         [description("角标颜色"), category("自定义")]
87         public color tipcolor
88         {
89             get { return tipcolor; }
90             set { tipcolor = value; }
91         }
92 
93         /// <summary>
94         /// 获取或设置控件的前景色。
95         /// </summary>
96         /// <value>the color of the fore.</value>
97         /// <permissionset>
98         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
99         /// </permissionset>
100         public override system.drawing.color forecolor
101         {
102             get
103             {
104                 return base.forecolor;
105             }
106             set
107             {
108                 base.forecolor = value;
109                 foreach (control c in this.controls)
110                 {
111                     c.forecolor = value;
112                 }
113             }
114         }
115         /// <summary>
116         /// 获取或设置控件显示的文字的字体。
117         /// </summary>
118         /// <value>the font.</value>
119         /// <permissionset>
120         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
121         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
122         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
123         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
124         /// </permissionset>
125         public override font font
126         {
127             get
128             {
129                 return base.font;
130             }
131             set
132             {
133                 base.font = value;
134                 foreach (control c in this.controls)
135                 {
136                     c.font = value;
137                 }
138             }
139         }
140 
141         /// <summary>
142         /// the m lst anchors
143         /// </summary>
144         dictionary<navigationmenuitemext, frmanchor> m_lstanchors = new dictionary<navigationmenuitemext, frmanchor>();
145         /// <summary>
146         /// initializes a new instance of the <see cref="ucnavigationmenuext"/> class.
147         /// </summary>
148         public ucnavigationmenuext()
149         {
150             initializecomponent();
151             items = new navigationmenuitemext[0];
152             if (controlhelper.isdesignmode())
153             {
154                 items = new navigationmenuitemext[4];
155                 for (int i = 0; i < 4; i++)
156                 {
157                     items[i] = new navigationmenuitemext()
158                     {
159                         text = "菜单" + (i + 1),
160                         anchorright = i >= 2
161                     };
162                 }
163             }
164         }
165 
166         /// <summary>
167         /// reloads the menu.
168         /// </summary>
169         private void reloadmenu()
170         {
171             try
172             {
173                 controlhelper.freezecontrol(this, true);
174                 this.controls.clear();
175                 if (items != null && items.length > 0)
176                 {
177                     foreach (var item in items)
178                     {
179                         var menu = (navigationmenuitemext)item;
180                         label lbl = new label();
181                         lbl.autosize = false;
182                         lbl.textalign = contentalignment.middlecenter;
183                         lbl.width = menu.itemwidth;
184                         lbl.text = menu.text;
185 
186                         lbl.font = font;
187                         lbl.forecolor = forecolor;
188 
189                         lbl.paint += lbl_paint;
190                         lbl.mouseenter += lbl_mouseenter;                    
191                         lbl.tag = menu;
192                         lbl.click += lbl_click;
193                         if (menu.anchorright)
194                         {
195                             lbl.dock = dockstyle.right;
196                         }
197                         else
198                         {
199                             lbl.dock = dockstyle.left;
200                         }
201                         this.controls.add(lbl);
202 
203                         lbl.bringtofront();
204                     }
205 
206 
207                 }
208             }
209             finally
210             {
211                 controlhelper.freezecontrol(this, false);
212             }
213         }
214 
215         /// <summary>
216         /// handles the click event of the lbl control.
217         /// </summary>
218         /// <param name="sender">the source of the event.</param>
219         /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param>
220         void lbl_click(object sender, eventargs e)
221         {
222             label lbl = sender as label;
223             if (lbl.tag != null)
224             {
225                 var menu = (navigationmenuitemext)lbl.tag;
226                 if (menu.showcontrol == null)
227                 {
228                     selectitem = menu;
229 
230                     while (m_lstanchors.count > 0)
231                     {
232                         try
233                         {
234                             foreach (var item in m_lstanchors)
235                             {
236                                 item.value.hide();
237                             }
238                         }
239                         catch { }
240                     }
241 
242                     if (clickitemed != null)
243                     {
244                         clickitemed(this, e);
245                     }
246                 }               
247             }
248         }
249         /// <summary>
250         /// handles the mouseenter event of the lbl control.
251         /// </summary>
252         /// <param name="sender">the source of the event.</param>
253         /// <param name="e">the <see cref="eventargs" /> instance containing the event data.</param>
254         void lbl_mouseenter(object sender, eventargs e)
255         {
256             label lbl = sender as label;
257             var menu = lbl.tag as navigationmenuitemext;
258             foreach (var item in m_lstanchors)
259             {
260                 m_lstanchors[item.key].hide();
261             }
262             if (menu.showcontrol != null)
263             {
264                 if (!m_lstanchors.containskey(menu))
265                 {
266                     m_lstanchors[menu] = new frmanchor(lbl, menu.showcontrol);
267                 }
268                 m_lstanchors[menu].show();
269                 m_lstanchors[menu].size = menu.showcontrol.size;
270             }
271         }
272         /// <summary>
273         /// handles the paint event of the lbl control.
274         /// </summary>
275         /// <param name="sender">the source of the event.</param>
276         /// <param name="e">the <see cref="painteventargs" /> instance containing the event data.</param>
277         void lbl_paint(object sender, painteventargs e)
278         {
279             label lbl = sender as label;
280             if (lbl.tag != null)
281             {
282                 var menu = (navigationmenuitemext)lbl.tag;
283                 e.graphics.setgdihigh();
284 
285                 if (menu.showtip)
286                 {
287                     if (!string.isnullorempty(menu.tiptext))
288                     {
289                         var rect = new rectangle(lbl.width - 25, lbl.height / 2 - 10, 20, 20);
290                         var path = rect.createroundedrectanglepath(5);
291                         e.graphics.fillpath(new solidbrush(tipcolor), path);
292                         e.graphics.drawstring(menu.tiptext, new font("微软雅黑", 8f), new solidbrush(color.white), rect, new stringformat() { alignment = stringalignment.center, linealignment = stringalignment.center });
293                     }
294                     else
295                     {
296                         e.graphics.fillellipse(new solidbrush(tipcolor), new rectangle(lbl.width - 20, lbl.height / 2 - 10, 10, 10));
297                     }
298                 }
299                 if (menu.icon != null)
300                 {
301                     e.graphics.drawimage(menu.icon, new rectangle(1, (lbl.height - 25) / 2, 25, 25), 0, 0, menu.icon.width, menu.icon.height, graphicsunit.pixel);
302                 }
303             }
304         }
305     }
306 }

 

最后的话

如果你喜欢的话,请到  点个星星吧