(八十四)c#Winform自定义控件-导航菜单(Ribbon菜单)-HZHControls
官网
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 ///2 /// The main menu height 3 /// 4 private int mainMenuHeight = 25; 5 6 /// 7 /// Gets or sets the height of the main menu. 8 /// 9 /// The height of the main menu. 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 /// 23 /// The expand height 24 /// 25 private int expandHeight = 125; 26 /// 27 /// Gets or sets the height of the expand. 28 /// 29 /// The height of the expand. 30 [Description("展开后高度"), Category("自定义")] 31 public int ExpandHeight 32 { 33 get { return expandHeight; } 34 set { expandHeight = value; } 35 } 36 /// 37 /// The is expand 38 /// 39 private bool isExpand = true; 40 /// 41 /// Gets or sets a value indicating whether this instance is expand. 42 /// 43 /// true if this instance is expand; otherwise, false. 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 /// 64 /// Occurs when [click itemed]. 65 /// 66 [Description("点击节点事件"), Category("自定义")] 67 68 public event EventHandler ClickItemed; 69 /// 70 /// The select item 71 /// 72 private NavigationMenuItemExt selectItem = null; 73 74 /// 75 /// Gets the select item. 76 /// 77 /// The select item. 78 [Description("选中的节点"), Category("自定义")] 79 public NavigationMenuItemExt SelectItem 80 { 81 get { return selectItem; } 82 private set { selectItem = value; } 83 } 84 85 /// 86 /// The items 87 /// 88 NavigationMenuItemExt[] items; 89 90 /// 91 /// Gets or sets the items. 92 /// 93 /// The items. 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 /// 110 /// The tip color 111 /// 112 private Color tipColor = Color.FromArgb(255, 87, 34); 113 114 /// 115 /// Gets or sets the color of the tip. 116 /// 117 /// The color of the tip. 118 [Description("角标颜色"), Category("自定义")] 119 public Color TipColor 120 { 121 get { return tipColor; } 122 set { tipColor = value; } 123 } 124 125 /// 126 /// 获取或设置控件的前景色。 127 /// 128 /// The color of the fore. 129 /// 130 /// 131 /// 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 /// 148 /// 获取或设置控件显示的文字的字体。 149 /// 150 /// The font. 151 /// 152 /// 153 /// 154 /// 155 /// 156 /// 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 /// 174 /// The m LST anchors 175 /// 176 Dictionary m_lstAnchors = new Dictionary ();
一些事件及辅助函数,处理大小改变时候和重新加载以及鼠标对应处理
1 ///2 /// Handles the SizeChanged event of the UCNavigationMenuOffice control. 3 /// 4 /// The source of the event. 5 /// The instance containing the event data. 6 void UCNavigationMenuOffice_SizeChanged(object sender, EventArgs e) 7 { 8 if (isExpand) 9 { 10 expandHeight = this.Height; 11 } 12 } 13 14 /// 15 /// Resets the child control. 16 /// 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 /// 48 /// Reloads the menu. 49 /// 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 /// 96 /// Handles the DoubleClick event of the lbl control. 97 /// 98 /// The source of the event. 99 /// The instance containing the event data. 100 void lbl_DoubleClick(object sender, EventArgs e) 101 { 102 IsExpand = !IsExpand; 103 } 104 /// 105 /// Handles the Click event of the lbl control. 106 /// 107 /// The source of the event. 108 /// The instance containing the event data. 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 /// 135 /// Handles the MouseEnter event of the lbl control. 136 /// 137 /// The source of the event. 138 /// The instance containing the event data. 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 /// 163 /// Handles the Paint event of the lbl control. 164 /// 165 /// The source of the event. 166 /// The instance containing the event data. 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 }
完整代码
1 // *********************************************************************** 2 // Assembly : HZH_Controls 3 // Created : 2019-10-12 4 // 5 // *********************************************************************** 6 //7 // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com 8 // 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 /// 29 /// Class UCNavigationMenuOffice. 30 /// Implements the 31 /// 32 /// 33 public partial class UCNavigationMenuOffice : UserControl 34 { 35 /// 36 /// The main menu height 37 /// 38 private int mainMenuHeight = 25; 39 40 /// 41 /// Gets or sets the height of the main menu. 42 /// 43 /// The height of the main menu. 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 /// 57 /// The expand height 58 /// 59 private int expandHeight = 125; 60 /// 61 /// Gets or sets the height of the expand. 62 /// 63 /// The height of the expand. 64 [Description("展开后高度"), Category("自定义")] 65 public int ExpandHeight 66 { 67 get { return expandHeight; } 68 set { expandHeight = value; } 69 } 70 /// 71 /// The is expand 72 /// 73 private bool isExpand = true; 74 /// 75 /// Gets or sets a value indicating whether this instance is expand. 76 /// 77 /// true if this instance is expand; otherwise, false. 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 /// 98 /// Occurs when [click itemed]. 99 /// 100 [Description("点击节点事件"), Category("自定义")] 101 102 public event EventHandler ClickItemed; 103 /// 104 /// The select item 105 /// 106 private NavigationMenuItemExt selectItem = null; 107 108 /// 109 /// Gets the select item. 110 /// 111 /// The select item. 112 [Description("选中的节点"), Category("自定义")] 113 public NavigationMenuItemExt SelectItem 114 { 115 get { return selectItem; } 116 private set { selectItem = value; } 117 } 118 119 /// 120 /// The items 121 /// 122 NavigationMenuItemExt[] items; 123 124 /// 125 /// Gets or sets the items. 126 /// 127 /// The items. 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 > 0) 137 { 138 selectItem = value[0]; 139 ResetChildControl(); 140 } 141 } 142 } 143 /// 144 /// The tip color 145 /// 146 private Color tipColor = Color.FromArgb(255, 87, 34); 147 148 /// 149 /// Gets or sets the color of the tip. 150 /// 151 /// The color of the tip. 152 [Description("角标颜色"), Category("自定义")] 153 public Color TipColor 154 { 155 get { return tipColor; } 156 set { tipColor = value; } 157 } 158 159 /// 160 /// 获取或设置控件的前景色。 161 /// 162 /// The color of the fore. 163 /// 164 /// 165 /// 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 /// 182 /// 获取或设置控件显示的文字的字体。 183 /// 184 /// The font. 185 /// 186 /// 187 /// 188 /// 189 /// 190 /// 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 /// 208 /// The m LST anchors 209 /// 210 Dictionary m_lstAnchors = new Dictionary (); 211 /// 212 /// Initializes a new instance of the class. 213 /// 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 >= 2 228 }; 229 } 230 } 231 } 232 233 /// 234 /// Handles the SizeChanged event of the UCNavigationMenuOffice control. 235 /// 236 /// The source of the event. 237 /// The instance containing the event data. 238 void UCNavigationMenuOffice_SizeChanged(object sender, EventArgs e) 239 { 240 if (isExpand) 241 { 242 expandHeight = this.Height; 243 } 244 } 245 246 /// 247 /// Resets the child control. 248 /// 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(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 finally 271 { 272 ControlHelper.FreezeControl(this, false); 273 } 274 } 275 } 276 } 277 278 279 /// 280 /// Reloads the menu. 281 /// 282 private void ReloadMenu() 283 { 284 try 285 { 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 else 312 { 313 lbl.Dock = DockStyle.Left; 314 } 315 this.panMenu.Controls.Add(lbl); 316 317 lbl.BringToFront(); 318 } 319 } 320 } 321 finally 322 { 323 ControlHelper.FreezeControl(this, false); 324 } 325 } 326 327 /// 328 /// Handles the DoubleClick event of the lbl control. 329 /// 330 /// The source of the event. 331 /// The instance containing the event data. 332 void lbl_DoubleClick(object sender, EventArgs e) 333 { 334 IsExpand = !IsExpand; 335 } 336 /// 337 /// Handles the Click event of the lbl control. 338 /// 339 /// The source of the event. 340 /// The instance containing the event data. 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 else 357 { 358 if (IsExpand) 359 { 360 selectItem = menu; 361 ResetChildControl(); 362 } 363 } 364 } 365 } 366 /// 367 /// Handles the MouseEnter event of the lbl control. 368 /// 369 /// The source of the event. 370 /// The instance containing the event data. 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 /// 395 /// Handles the Paint event of the lbl control. 396 /// 397 /// The source of the event. 398 /// The instance containing the event data. 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 else 417 { 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 }
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧