(八十四)c#Winform自定義控制項-導航菜單(類Office菜單)

来源:https://www.cnblogs.com/bfyx/archive/2019/10/12/11660212.html
-Advertisement-
Play Games

前提 入行已經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 支持一下吧

歡迎前來交流探討: 企鵝群568015492 企鵝群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 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         }

完整代碼

  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         	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 異常處理一直是所有編程語言不可避免需要考慮的問題,C 的非同步方法的異常處理和同步方法並無差別,同樣要藉助 try catch 語句捕獲異常。 首先編寫一個拋出異常的方法 常見的 try catch 處理語句。 async Task方法的異常存儲在Task對象中,Task有一個Exception屬性。 ...
  • 前言 在.NET Core 2.0發佈的時候,博主也趁熱使用ASP.NET Core 2.0寫了一個獨立的博客網站,現如今恰逢.NET Core 3.0發佈之際,於是將該網站進行了升級。 下麵就記錄升級過程中遇到的一些變化和問題。同時也小廣告一波,歡迎大家多來我的博客逛逛:不落閣 - 一個.NET程 ...
  • 場景 Winform控制項-DevExpress18下載安裝註冊以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100061243 在上面成功安裝DevExpress控制項後,需要實現以下圖形按鈕菜單欄效果 註: 博 ...
  • 作者:依樂祝原本鏈接:https://www.cnblogs.com/yilezhu/p/9947905.html 需要安裝Redis => https://www.runoob.com/redis/redis-install.html ...
  • 1 先把IrisSkin2.dll文件添加到當前項目引用(解決方案資源管理器->當前項目->引用->右鍵->添加引用,找到IrisSkin2.dll文件.....之後就不用我說了吧^_^).IrisSkin2.dll文件最好放在當前項目binDebug文件中. 2. 然後把IrisSkin2.dll ...
  • 解決方法一:用記事本打開*.licx,裡面寫的全是第三方插件的指定DLL,刪除錯誤信息,保存,關閉,重新生成解決方案。解決方法二:把項目文件夾下Properties文件夾下的licenses.licx文件刪除,重新編譯即可;解決方法三:文本方式打開*.csproj文件,在文件中查找licenses. ...
  • MimeKit / MailKit 支持最新的國際化的電子郵件標準,是.NET 中為一個支持完整支持這些標準電子郵件庫,最近正式發佈了1.0版本。如果你想做所有與的電子郵件相關的事情,看看 MimeKit 和 MailKit。我保證你不會失望,它支持.NET/Mono的所有平臺,包括行動電話、平板等 ...
  • private void WriteLoginJsonData(object jsonData) { using (FileStream writerFileStream = new FileStream(JsonDataFile, FileMode.OpenOrCreate)) { using..... ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...