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