Winform界面中實現(xiàn)菜單列表的動態(tài)個性化配置管理方法
在我們一般的應用系統(tǒng)里面,由于系統(tǒng)是面向不同類型的用戶,我們所看到的菜單會越來越多,多一點的甚至上百個,但是我們實際工作接觸的菜單可能就是那么幾個,那么對于這種龐大的菜單體系,尋找起來非常不便。因此對菜單的個性化配置就顯得尤為重要,本篇隨筆就是基于這樣的理念,提供用戶對可見菜單進行一個動態(tài)配置,只選自己喜歡、常用的菜單顯示出來即可,菜單的配置存儲在數(shù)據(jù)庫里面,在不同的客戶端體驗都是一樣。本篇隨筆主要介紹實現(xiàn)這樣的功能的一個完整思路,部分代碼邏輯可供參考。
1、 菜單列表的動態(tài)個性化配置的過程
在我們有些軟件里面,我們可能在界面上頂部放置菜單,也可能在界面的左側放置樹形列表菜單,這種情況都有可能,本篇摘取其中之一,左側菜單進行一個介紹菜單的配置處理。
例如我們在左側根據(jù)用戶權限展示相關的菜單信息,動態(tài)生成整個列表展示,大致的界面效果如下所示。
然后在功能列表上提供一個右鍵的菜單進行菜單的刷新、配置管理,如下界面所示。
通過配置功能,我們讓用戶進入一個配置管理界面,在其中配置顯示自己感興趣的菜單,然后進行保存即可,保存后同時刷新界面的功能菜單顯示。
以上幾個界面效果就是為了介紹整個菜單配置管理的一般過程,之所以把界面效果放在前面介紹,就是能夠讓我們有一個類似原型設計方式的感性認識,了解了相關的處理過程,我們就可以著手通過編碼的方式來實現(xiàn)這個處理邏輯了。
2、菜單動態(tài)個性化配置的功能實現(xiàn)
上面介紹了大概的界面效果,有了參考,我們可以把它的實現(xiàn)思路通過代碼實現(xiàn)出來。
1)參數(shù)的數(shù)據(jù)存儲
首先我們需要了解,用戶配置可以通過XML保存在本地,也可以通過數(shù)據(jù)庫存儲保存在服務器,后者在分布式的客戶端的時候,可以處處一樣,這樣就不會造成體驗上的差異,因此我們這里采用存儲在數(shù)據(jù)庫的方案。
這個存儲我們沿用我之前介紹過的配置管理組件(SettingsProvider.net),我在隨筆《Winform開發(fā)框架之參數(shù)配置管理功能實現(xiàn)-基于SettingsProvider.net的構建》中對它的使用進行了詳細的介紹。
這個配置管理組件SettingsProvider.net使用起來也是比較方便的,可以選擇存儲在本地的對象,也可以選擇存儲在數(shù)據(jù)庫的存儲對象。
首先我們先定義一個存儲的參數(shù)類,這個是使用這個組件所必須的存儲對象信息,如下代碼所示。
/// <summary> /// 用來控制人員管理顯示菜單的參數(shù)配置 /// </summary> public class UserMenuParameter { [DefaultValue("")] [Description("用戶ID")] public string UserID { get; set; } [Description("用戶設置可見的菜單")] public Dictionary<string, bool> VisibleDict { get; set; } }
需要獲取或存儲這個對象信息的時候,我們初始化幾個管理類,如下代碼所示。
//參數(shù)存儲所需的相關對象 private SettingsProvider settings; private ISettingsStorage store; private UserMenuParameter parameter;
然后在配置管理界面窗體里面,初始化這幾個對象,如下代碼所示。
// PortableStorage: 在運行程序目錄創(chuàng)建一個setting的文件記錄參數(shù)數(shù)據(jù) // DatabaseStorage:在數(shù)據(jù)庫TB_UserParameter表存儲用戶配置參數(shù) store = new DatabaseStorage(LoginUserInfo.ID); settings = new SettingsProvider(store); parameter = settings.GetSettings<UserMenuParameter>();
這樣我們就可以根據(jù)用戶的ID,獲取對應記錄的信息并轉換為相關的對象了,如果我們需要把修改的信息寫會到存儲介質里面,代碼如下所示。
try { parameter = settings.GetSettings<UserMenuParameter>(); parameter.VisibleDict = dict; parameter.UserID = LoginUserInfo.ID; settings.SaveSettings<UserMenuParameter>(parameter); ProcessDataSaved(sender, e);//觸發(fā)外部事件 this.DialogResult = System.Windows.Forms.DialogResult.OK; } catch (Exception ex) { LogHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); return; }
2)配置管理界面的實現(xiàn)
解決了參數(shù)的獲取及存儲功能后,我們需要編寫一個界面來管理用戶的菜單配置,也就是我們前面介紹的菜單配置管理界面。
我們這個界面的定義代碼如下所示。
其中參數(shù)的數(shù)據(jù)存儲就是應用了前面介紹的代碼,這里需要根據(jù)用戶的配置項初始化樹形菜單的顯示處理,通過InitTree的函數(shù)實現(xiàn)菜單的顯示。
在顯示菜單前,我們先介紹一下功能菜單顯示的規(guī)則,僅當參數(shù)存在對應記錄,并且該記錄顯式設置不可見,菜單才不可見,否則默認菜單是可以看到的。
這樣確保了,在參數(shù)沒有配置前,所有的菜單對當前用戶是可見的,只有用戶設置為不不可見,該菜單才不顯示為不可見。
/// <summary> /// 獲取菜單是否可見。 /// 僅當參數(shù)存在對應記錄,并且該記錄顯式設置不可見,菜單才不可見,否則默認菜單是可以看到的。 /// </summary> /// <param name="id">菜單ID</param> /// <returns></returns> private bool GetVisibleMenu(string id) { bool result = true; if (parameter != null) { var dict = parameter.VisibleDict; if(dict != null && dict.ContainsKey(id)) { result = dict[id]; } } return result; }
顯示菜單的相關處理邏輯,就是根據(jù)上面的判斷,然后確定是否勾選記錄,如下代碼所示。
存儲用戶勾選的記錄的時候,我們需要遍歷整個樹節(jié)點,判斷勾選了那些選項,然后把它保存數(shù)據(jù)庫即可。
/// <summary> /// 遞歸獲取選中的樹節(jié)點集合 /// </summary> /// <param name="node">樹節(jié)點</param> /// <param name="dict">字典集合</param> /// <returns></returns> private Dictionary<string, bool> GetTreeSelection(TreeNode node, Dictionary<string, bool> dict) { if (node.Tag != null) { var check = node.Checked; var menuId = string.Concat(node.Tag); if(!dict.ContainsKey(menuId)) { dict.Add(menuId, check); } } foreach (TreeNode child in node.Nodes) { GetTreeSelection(child, dict); } return dict; }
參數(shù)的保存操作如下所示。
/// <summary> /// 保存用戶配置信息 /// </summary> private void btnOK_Click(object sender, EventArgs e) { //獲取用戶勾選的樹列表,存放在字典集合里面 var dict = new Dictionary<string, bool>(); foreach(TreeNode node in this.treeView1.Nodes) { GetTreeSelection(node, dict); } try { //重新獲取參數(shù)信息,并設置新值后保存 parameter = settings.GetSettings<UserMenuParameter>(); parameter.VisibleDict = dict; parameter.UserID = LoginUserInfo.ID; settings.SaveSettings<UserMenuParameter>(parameter); ProcessDataSaved(sender, e);//觸發(fā)外部事件 this.DialogResult = System.Windows.Forms.DialogResult.OK; } catch (Exception ex) { LogHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); return; } }
3)主界面的相關處理
以上處理完成后,我們在主界面的工具欄右鍵菜單添加一個菜單項,用來進入配置界面的,如下邏輯代碼所示。
private void tool_MenuSetting_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { MenuSetting(); } /// <summary> /// 配置菜單項 /// </summary> private void MenuSetting() { FrmMenuSetting dlg = new FrmMenuSetting(); dlg.OnDataSaved += (s, arg) => { //用戶保存參數(shù)后,提示用戶更新樹形列表 InitToolbar(); }; dlg.ShowDialog(); }
這樣界面配置參數(shù)并保存后,界面的樹形菜單會及時得到更新處理。
另外,我們主界面的樹形列表,也要根據(jù)配置參數(shù)的信息作相關的調整,如果用戶配置了不顯示某個菜單,那么主界面也要根據(jù)配置參數(shù)控制顯示。
3、總結
以上就是整個菜單列表的動態(tài)個性化配置管理的整體思路和實現(xiàn)步驟代碼,主要的界面考量還是以用戶的視覺來考慮界面的布局和功能,如果在幾百個菜單項中尋找?guī)讉€常用的菜單,每次是一個比較耗時無聊的操作,因此提供一個個性化的界面,根據(jù)工作情況的不同,顯示一些和自己相關的功能即可。
例如有些情況下,我們的菜單顯示,希望通過工具欄的方式進行控制顯示,如下界面效果所示。
那么配置維護界面還是差不多,只是我們控制工具欄的顯示邏輯有所不同而已,對于RibbonPage及其功能菜單的動態(tài)生成處理如下所示。
本篇隨筆主要還是希望讀者借鑒配置存儲和菜單個性化管理的思路,具體的邏輯會因用戶界面的不同,使用的控件不同而有所差異,不過總體思路是一致的即可。
例如有些參數(shù)的配置管理,可以統(tǒng)一使用一個配置管理界面進行維護,如我之前的隨筆介紹的界面功能一樣。
以上這篇Winform界面中實現(xiàn)菜單列表的動態(tài)個性化配置管理方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持我們。
上一篇:C#使用Gembox.SpreadSheet向Excel寫入數(shù)據(jù)及圖表的實例
欄 目:C#教程
本文標題:Winform界面中實現(xiàn)菜單列表的動態(tài)個性化配置管理方法
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5370.html
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新聞效果的方法
- 01-10C#實現(xiàn)Winform中打開網頁頁面的方法
- 01-10winform實現(xiàn)創(chuàng)建最前端窗體的方法
- 01-10C#實現(xiàn)由四周向中心縮小的窗體退出特效
- 01-10WinForm實現(xiàn)自定義右下角提示效果的方法
- 01-10Extjs4如何處理后臺json數(shù)據(jù)中日期和時間
- 01-10.net2.0+ Winform項目實現(xiàn)彈出容器層


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結
- 08-05DEDE織夢data目錄下的sessions文件夾有什