轉帖|使用教程|編輯:龔雪|2024-03-01 11:35:41.217|閱讀 104 次
概述:本文主要介紹如何在WinForms應用界面中實現工具欄/菜單的動態呈現,希望幫助到大家~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
在Winform系統開發中,為了對系統的工具欄/菜單進行動態的控制,我們對系統的工具欄/菜單進行動態配置,這樣可以把系統的功能彈性發揮到極致。通過動態工具欄/菜單的配置方式,我們可以很容易的為系統新增所需的功能,通過權限分配的方式,可以更有效的管理系統的菜單分配到不同的角色用戶,也就是插件化的處理方式。
PS:給大家推薦一個C#開發可以用到的界面組件——DevExpress WinForms,它能完美構建流暢、美觀且易于使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕松勝任!
DevExpress技術交流群9:909157416 歡迎一起進群討論
我們一般的應用系統里面,由于系統是面向不同類型的用戶,所看到的菜單會越來越多,多一點的甚至上百個,但是實際工作接觸的菜單可能就是那么幾個,那么對于這種龐大的菜單體系,尋找起來非常不便。因此對菜單的個性化配置就顯得尤為重要。
但在我們開發的時候,為了方便調試和測試基礎功能,有時候有需要直接在Ribbon工具欄或者菜單中固定一些功能的入口,以便快速開發某些常見功能,那么我們可以在系統中增加一個變量來控制動態展示還是采用靜態工具欄/菜單的方式。
因此我們在主窗體中使用菜單/工具欄,分為了預設的靜態模式(方便測試)和動態模式(實際應用)。
以上圖示是預設的一些基礎入口,我們可以先具體測試某些功能,這樣不會打斷實際的開發工作,而在系統部署給客戶的時候,采用動態模式構建的工具欄/菜單,用戶在登錄的時候,首先清空預設菜單,在加載擁有的菜單/工具欄,這樣就不會相互影響。
我們在程序的主窗口,增加一個變量來控制是否動態即可,默認為false,也就是靜態控件模式。開發完成后,部署的時候,把它改為True即可,如下代碼。
/// <summary> /// 程序主界面 /// </summary> public partial class MainForm : RibbonForm { /// <summary> /// 是否標記為動態生成頂部按鈕欄,從數據庫讀取動態菜單信息。 /// </summary> private bool useRemoteMenu = false;
因此我們可以根據這個開關變量來處理菜單的加載處理,如下代碼函數所示是處理工具欄、菜單的加載邏輯。
/// <summary> /// 初始化左側功能菜單樹列表 /// </summary> private void InitToolbar() { //如果標記為動態生成,那么預設的菜單將清空 if (useRemoteMenu) { //初始化Ribbon控制類 if (ribbonHelper == null) { ribbonHelper = new RibbonPageHelper(this, ref this.ribbonControl); } ribbonHelper.ClearAllPages();//預設的菜單清空 ribbonHelper.AddPages();//動態創建界面菜單對象 } //重新加入應用程序菜單,否則訪問出錯 this.applicationMenu1.ItemLinks.Clear(); this.applicationMenu1.AddItems(new DevExpress.XtraBars.BarItem[] { this.menu_QuitSystem, this.menu_Relogin }); //根據權限屏蔽菜單對象 InitAuthorizedUI(); if (this.ribbonControl.Pages.Count > 0) { ribbonControl.SelectedPage = ribbonControl.Pages[0]; } }
其中 RibbonPageHelper 輔助類就是用來動態構建Ribbon工具欄的,如果是靜態,則默認采用設計時刻的工具按鈕即可。
其中ClearAllPages就是清空按鈕。
/// <summary> /// 清空所有按鈕 /// </summary> public void ClearAllPages() { if(this.control != null && this.control.Pages != null) { this.control.Pages.Clear(); } }
而動態構建的工具欄按鈕,就是根據用戶的角色身份所控制的按鈕處理的。
而構建菜單/工具欄按鈕的時候,我們主要就是創建工具欄按鈕的名稱、圖標、以及響應的事件即可,如下代碼所示。
/// <summary> /// 動態創建Ribbon的按鈕項目 /// </summary> /// <param name="menuInfo">菜單信息</param> /// <returns></returns> private BarButtonItem CreateButonItem(MenuNodeInfo menuInfo) { //添加功能按鈕(三級菜單) var button = new BarButtonItem(); button.PaintStyle = BarItemPaintStyle.CaptionGlyph; button.LargeGlyph = LoadIcon(menuInfo); button.Glyph = LoadIcon(menuInfo); button.Name = menuInfo.Id; button.Caption = menuInfo.Name; button.Tag = menuInfo.WinformType; button.ItemClick += (sender, e) => { if (button.Tag != null && !string.IsNullOrEmpty(button.Tag.ToString())) { LoadPlugInForm(string.Concat(button.Tag)); } else { MessageDxUtil.ShowTips(button.Caption); } }; return button; }
其中 LoadPlugInForm 函數就是我們加載菜單處理的邏輯,一般就是根據配置信息動態構建出一個窗體即可。
因此我們需要了解動態菜單的項目中,具體的配置信息是什么,才知道如何具體使用反射的方法,來構建出一個窗體的實例顯示。
如上圖所示的內容,前面部分為窗體類的全局名稱,而后面是窗體所在的程序集名稱,這樣我們根據程序集的名稱,菜單或者按鈕的單擊事件中加載窗體類顯示即可。我們一般以逗號分開兩個部分,如果是當前程序集,也可以忽略,有系統自動解析加上即可。
string[] itemArray = typeName.Split(new char[]{',',';'});
然后根據內容解析窗體類和具體的程序集路徑即可。
string type = itemArray[0].Trim(); string filePath = (itemArray.Length > 1) ? itemArray[1].Trim() : Assembly.GetExecutingAssembly().GetName().Name;//必須是相對路徑
最后稍微處理下,通過具體路徑構建處理即可。
//從程序集中加載窗體類,設置為多文檔的模式 string dllFullPath = Path.Combine(Application.StartupPath, filePath); var tempAssembly = Assembly.LoadFrom(dllFullPath); if (tempAssembly != null) { Type objType = tempAssembly.GetType(type); if (objType != null) { LoadMdiForm(this.mainForm, objType, isShowDialog); } }
多窗體的顯示,先判斷是否存在,如果不存在則創建,存在則激活即可。
if (isShowDialog) { tableForm.ShowDialog(); } else { tableForm.MdiParent = mainDialog; tableForm.Show(); } tableForm.BringToFront(); tableForm.Activate();
這樣就是動態工具欄、菜單的處理邏輯了。
本文轉載自:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: