首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

Windows Forms 選單設計完全攻略:MainMenu、ContextMenu、MenuItem 與事件處理實戰

     編輯:關於C#

前言:選單是桌面應用程式的導航中樞

Windows Forms 提供 MainMenu(主選單列)、ContextMenu(右鍵彈出選單)、MenuItem(選單項目)三大核心類別,繼承自抽象基類 Menu。本文系統整理類別階層、建構函式多載、屬性配置、動態建立/修改/刪除選單項目、事件繫結模式、完整實戰範例與最佳實務。

一、類別繼承體系與核心類別


Object
└─ MarshalByRefObject
   └─ Component
      └─ Menu (abstract)
         ├─ MainMenu          // 表單頂端選單列容器
         ├─ ContextMenu       // 右鍵彈出選單容器
         └─ MenuItem          // 單一選單項目(可巢狀形成子選單)

Menu.MenuItemCollection 實作 IList/ICollection/IEnumerable,提供 Add/AddRange/Remove/RemoveAt/Clear/Contains/IndexOf/CopyTo 等集合操作。

二、MenuItem 詳細解析

2.1 五種建構函式多載

建構函式用途範例
MenuItem()空項目,後續設定屬性new MenuItem { Text = "&File" }
MenuItem(string text)指定顯示文字new MenuItem("&New")
MenuItem(string, EventHandler)文字 + Click 事件new MenuItem("&Open", OnOpenClick)
MenuItem(string, MenuItem[])文字 + 子選單陣列new MenuItem("&View", new[]{item1, item2})
MenuItem(string, EventHandler, Shortcut)文字 + Click + 快捷鍵new MenuItem("&Save", OnSave, Shortcut.CtrlS)

2.2 關鍵屬性速查表

屬性型別功能備註
Textstring顯示文字,& 前綴字元變為底線(Alt 快捷鍵)"&File" → File
Checkedbool前方顯示核取記號 (✓)互斥選項需自行邏輯控制
Enabledbool是否可點選,灰顯不可用預設 true
Visiblebool是否顯示預設 true
ShortcutShortcut功能鍵組合(CtrlS、F1 等)需 ShowShortcut=true 顯示
ShowShortcutbool是否在選單右側顯示快捷鍵文字預設 true
BarBreakbool換欄並顯示分隔線工具列風格選單
Breakbool換欄不顯示分隔線
DefaultItembool粗體顯示,雙擊父選單觸發單一父選單僅一個
Indexint在父集合中的位置(可設定重新排序)唯讀於設計器
IsParentbool是否擁有子選單唯讀
MenuItemsMenuItemCollection子選單集合動態增刪改查
ParentMenu父選單容器(MainMenu/ContextMenu/MenuItem)唯讀
MergeOrder/MergeTypeint/MenuMergeMDI 子表單選單合併行為進階主題

2.3 分隔線

Text = "-" → 自動轉為分隔線(不可點選、無事件)。

三、動態建立主選單


var mainMenu = new MainMenu();

// 頂層項目
var fileItem = new MenuItem("&File");
var editItem = new MenuItem("&Edit");
var viewItem = new MenuItem("&View");

// File 子選單
fileItem.MenuItems.AddRange(new MenuItem[] {
    new MenuItem("&New", OnNewClick, Shortcut.CtrlN),
    new MenuItem("&Open", OnOpenClick, Shortcut.CtrlO),
    new MenuItem("-"), // 分隔線
    new MenuItem("E&xit", OnExitClick)
});

// Edit 子選單
editItem.MenuItems.AddRange(new MenuItem[] {
    new MenuItem("&Copy", OnCopyClick, Shortcut.CtrlC),
    new MenuItem("&Paste", OnPasteClick, Shortcut.CtrlV)
});

// 加入主選單
mainMenu.MenuItems.AddRange(new MenuItem[] { fileItem, editItem, viewItem });

// 指派給表單
this.Menu = mainMenu;

四、動態建立右鍵彈出選單


var contextMenu = new ContextMenu();
contextMenu.MenuItems.AddRange(new MenuItem[] {
    new MenuItem("&Refresh", OnRefreshClick),
    new MenuItem("&Properties", OnPropertiesClick),
    new MenuItem("-"),
    new MenuItem("E&xit", OnExitClick)
});

// 指派給表單或任意控制項
this.ContextMenu = contextMenu;
textBox1.ContextMenu = contextMenu; // 控制項層級覆蓋

// 程式碼觸發顯示(滑鼠座標)
contextMenu.Show(this, new Point(e.X, e.Y)); // 在 MouseDown/Click 事件中

五、事件處理:委派模式與多重訂閱

5.1 基本繫結


// 單一處理器
menuItem.Click += OnMenuClick;

// 多重處理器(依加入順序執行)
menuItem.Click += OnFirstHandler;
menuItem.Click += OnSecondHandler;

// 移除處理器
menuItem.Click -= OnFirstHandler;

5.2 事件處理器簽章


private void OnMenuClick(object sender, EventArgs e) {
    var item = (MenuItem)sender;
    MessageBox.Show($"您點選了:{item.Text}");
}
  • sender:引發事件的 MenuItem 實例。
  • e:EventArgs(Click 無額外資料),DrawItemEventArgs(OwnerDraw)、MeasureItemEventArgs(自訂量測)。

5.3 進階事件

事件觸發時機EventArgs 型別用途
Click使用者點選EventArgs命令執行
Popup彈出選單即將顯示EventArgs動態啟用/停用/可見項目
Select游標移至項目EventArgs狀態列提示
DrawItemOwnerDraw 模式繪製DrawItemEventArgs自訂外觀(圖示、顏色、字型)
MeasureItemOwnerDraw 模式量測MeasureItemEventArgs自訂項目尺寸

六、完整實戰範例:動態選單管理器


public partial class MenuDemoForm : Form
{
    private MainMenu _mainMenu;
    private ContextMenu _contextMenu;

    public MenuDemoForm()
    {
        InitializeComponent();
        BuildMainMenu();
        BuildContextMenu();
    }

    private void BuildMainMenu()
    {
        _mainMenu = new MainMenu();
        var file = new MenuItem("&File");
        file.MenuItems.Add(new MenuItem("&New", (s,e) => MessageBox.Show("New")));
        file.MenuItems.Add(new MenuItem("&Open", (s,e) => MessageBox.Show("Open")));
        file.MenuItems.Add(new MenuItem("-"));
        file.MenuItems.Add(new MenuItem("E&xit", (s,e) => Close()));
        _mainMenu.MenuItems.Add(file);
        _mainMenu.MenuItems.Add(new MenuItem("&Edit"));
        _mainMenu.MenuItems.Add(new MenuItem("&Help"));
        this.Menu = _mainMenu;
    }

    private void BuildContextMenu()
    {
        _contextMenu = new ContextMenu();
        _contextMenu.Popup += (s, e) => {
            // 動態調整:若剪貼簿有文字才啟用 Paste
            _contextMenu.MenuItems[1].Enabled = Clipboard.ContainsText();
        };
        _contextMenu.MenuItems.Add(new MenuItem("&Copy", (s,e) => Clipboard.SetText("Copied!")));
        _contextMenu.MenuItems.Add(new MenuItem("&Paste", (s,e) => MessageBox.Show(Clipboard.GetText())));
        this.ContextMenu = _contextMenu;
    }

    // 按鈕動態新增/移除主選單項目
    private void btnAddMenu_Click(object sender, EventArgs e)
    {
        var item = new MenuItem($"Item {_mainMenu.MenuItems.Count + 1}");
        item.Click += (s, e) => MessageBox.Show(((MenuItem)s).Text);
        _mainMenu.MenuItems.Add(item);
    }

    private void btnRemoveMenu_Click(object sender, EventArgs e)
    {
        if (_mainMenu.MenuItems.Count > 0) {
            var last = _mainMenu.MenuItems[_mainMenu.MenuItems.Count - 1];
            _mainMenu.MenuItems.Remove(last);
        }
    }
}

七、設計器支援與最佳實務

  1. Visual Studio 設計器:工具箱拖曳 MainMenu/ContextMenu,屬性視窗編輯項目、事件,自動產生 InitializeComponent 程式碼。
  2. 資源本地化:Text、Shortcut 等屬性可透過 .resx 多語系。
  3. MDI 選單合併:設定 MergeOrder/MergeType(Add/Replace/MergeItems)實現子表單選單自動合併至父表單。
  4. OwnerDraw:OwnerDraw = true + DrawItem/MeasureItem 事件實作自訂繪製(圖示、漸層、高亮)。
  5. 快捷鍵衝突:表單 KeyPreview = true 統一攔截,或依賴選單原生 Shortcut 自動處理。
  6. 記憶體洩漏防範:動態建立大量選單項目時,移除前解除事件訂閱(-=),避免委派持有參考阻礙 GC。

八、從 .NET Framework 遷移至 .NET 6+ / .NET 8 的注意事項

  • Windows Forms 僅支援 Windows 平台(需 `net8.0-windows`)。
  • 高 DPI 感知:專案屬性勾選「DPI 感知」,或程式碼 Application.SetHighDpiMode(HighDpiMode.PerMonitorV2)。
  • Application.EnableVisualStyles() 仍需在 Main 最前呼叫啟用視覺樣式。
  • 設計器體驗在 VS 2022 完整支援,熱重載可即時預覽選單變更。

結語

Windows Forms 選單系統以 Menu 抽象基類統一 MainMenu/ContextMenu/MenuItem,配合 MenuItemCollection 強型別集合操作,提供直覺且強大的動態選單建構能力。掌握建構函式多載、屬性語意、事件委派模式、OwnerDraw 進階繪製、MDI 合併與動態管理技巧,即能打造專業級桌面應用程式導航體驗。雖然生態逐漸轉向 WPF/MAUI/Blazor Hybrid,但 WinForms 於企業內部工具、舊系統維護、快速原型開發仍具不可替代的生產力優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved