winform快速開發平臺 -> 通用權限管理之動態菜單

這幾個月一直忙APP的項目,沒來得及更新項目,想一想該抽出時間整理一下開發思路,跟你們分享,同時也但願獲得寶貴的建議。html

先說一下咱們的權限管理的的設計思路,首先一個企業信息化管理系統必定會用到權限管理, 那麼一個動態的菜單在企業信息化管理系統佔有必定的份量。數據庫

下面介紹個人一些思路。編程

因爲原聲的winform界面美觀性不夠, 系統採用dotnetbar第三方控件來輔助編程。框架

首先咱們看紅色方框部分爲咱們的動態模塊功能。這樣咱們得到到了如下幾個信息, 咱們須要記錄模塊功能, 而且須要父子集關係, 那麼對應的咱們就須要在數據庫中創建一張表來維護咱們的動態菜單模塊。咱們舉例命名爲BaseModuleTabel, 那麼會有一下的內容,Id ParentId Name,而且因爲須要跟不一樣的用戶有對應的關係, 咱們還要創建用戶以及菜單的關係表,來維護用戶與菜單的權限關係。  post

這裏就不介紹表的設計。咱們先來看看在dotnetbar中如何呈現動態菜單邏輯。this

咱們先從數據庫中獲取到全部菜單模塊。並經過循環便利動態的加載模塊按鈕。 並添加對應的模塊按鈕事件,url

 1         /// <summary>
 2         /// 加載菜單
 3         /// </summary>
 4         private void LoadMenu()
 5         {
 6             var parentEntity = _baseModuleBll.Repository().FindEntity("ParentId", "0");
 7 
 8             var result = _baseModuleBll.GetModuleList().Select(p => new BaseTreeViewMenuModel()
 9             {
10                 Id = p.ModuleId,
11                 ParentId = p.ParentId,
12                 Name = p.FullName,
13                 Class = p.Location,
14                 Namespace = StringHelper.SubFirstChart(p.Location, '.'),
15                 IsForm = p.Target == "iframe"
16             }).ToList();
17             RibbonTabItem ribbonTabItemFrist = null;
18             var rabbonTabItemEntities = result.Where(p => p.ParentId == parentEntity.ModuleId);
19             foreach (var ribbonTabItemEntity in rabbonTabItemEntities)
20             {
21                 var ribbonPanel = new RibbonPanel
22                 {
23                     Text = ribbonTabItemEntity.Name,
24                     Dock = DockStyle.Fill
25                 };
26                 var ribbonTabItem = new RibbonTabItem
27                 {
28                     Text = ribbonTabItemEntity.Name,
29                     Panel = ribbonPanel
30                 };
31                 if (ribbonTabItemFrist == null)
32                     ribbonTabItemFrist = ribbonTabItem;
33                 this.ribbonControlMenu.Controls.Add(ribbonPanel);
34                 this.ribbonControlMenu.Items.Add(ribbonTabItem);
35 
36                 var ribbonBar = new RibbonBar { Text = ribbonTabItemEntity.Name };
37                 var buttonItemEntities = result.Where(p => p.ParentId == ribbonTabItemEntity.Id);
38                 foreach (var buttonItem in buttonItemEntities.Select(buttonItemEntitiy =>
39                     new ButtonItem("ButtonItem" + buttonItemEntitiy.Name)
40                     {
41                         Text = buttonItemEntitiy.Name,
42                         Tag = buttonItemEntitiy
43                     }))
44                 {
45                     buttonItem.Click += ButtonItem_Click;
46                     ribbonBar.Items.Add(buttonItem);
47                     ribbonPanel.Controls.Add(ribbonBar);
48                 }
49             }
50             this.ribbonControlMenu.SelectedRibbonTabItem = ribbonTabItemFrist;
51 
52         }
53 
54         #endregion

固然咱們的框架採用了反射機制來實現組件式開發。一般在一個項目裏,爲了下降耦合度,我一邊將模塊力度最小話,並將按必定的規則分類, 處理成摸個模塊,在咱們的系統中並不影響彼此開發的同時, 每一個成員均可以獨立的去完成本身的小任務, 說句很差聽的, 就算是能力不好的新手,開發出來的耦合度極高的代碼, 經過這樣一種方式,他的影響範圍也牢牢在與他的模塊內, 並不影響其餘模塊操做。 僅做爲我的的一種方式,固然經過咱們的代碼生成器,會生成必定的代碼規範,這雖然能避免一些, 但起不到決定性的做用。 畢竟每一個人的能力也是大不相同的。做爲PM咱們須要作的就是下降項目總體風險,按照規定的項目週期,制定完善的項目計劃,系統模塊劃分力度越大,項目把控的越高。 spa

下面打開點擊模塊按鈕來,經過反射來實現對各個模塊的初始化以及加載。代碼效率目前開無太大障礙。固然若是一個模塊dll你要弄個幾百兆,那我也只能無語了。你的力度相對較小,會跟你反射的時間掛鉤的。設計

 1         /// <summary>
 2         /// 打開模塊菜單
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void ButtonItem_Click(object sender, EventArgs e)
 7         {
 8             var isOpened = false;
 9             var buttonItem = (ButtonItem)sender;
10             var baseTreeViewMenuModel = (BaseTreeViewMenuModel)buttonItem.Tag;
11             if (baseTreeViewMenuModel == null) return;
12             if (!baseTreeViewMenuModel.IsForm) return;
13             if (string.IsNullOrWhiteSpace(baseTreeViewMenuModel.Namespace)) return;
14             //遍歷現有的Tab頁面,若是存在,那麼設置爲選中便可
15             foreach (var tabitem in
16                 superTabControlContent.Tabs.Cast<SuperTabItem>()
17                 .Where(tabitem => tabitem.Name == "superTabItem" + baseTreeViewMenuModel.Name))
18             {
19                 superTabControlContent.SelectedTab = tabitem;
20                 isOpened = true;
21                 break;
22             }
23             if (isOpened) return;
24             var dll = Application.StartupPath + "\\" + baseTreeViewMenuModel.Namespace + ".dll";
25             if (!File.Exists(dll)) return;
26             var assembly = Assembly.LoadFrom(dll);
27             var type = assembly.GetType(baseTreeViewMenuModel.Class);
28             if (type == null) return;
29             var form = (FormBase)Activator.CreateInstance(type);
30             form.ModuleId = baseTreeViewMenuModel.Id;
31             form.FormBorderStyle = FormBorderStyle.None;
32             form.TopLevel = false;
33             form.Visible = true;
34             form.Dock = DockStyle.Fill;
35             var superTabItem = superTabControlContent.CreateTab(baseTreeViewMenuModel.Name);
36             superTabItem.Text = baseTreeViewMenuModel.Name;
37             superTabItem.Name = "superTabItem" + baseTreeViewMenuModel.Name;
38             superTabItem.AttachedControl.Controls.Add(form);
39             superTabControlContent.SelectedTab = superTabItem;
40         }
41          
42         #endregion

經過以上的代碼咱們就能夠實現以下圖所示的動態菜單功能 。代碼規範

分享是美德,要提倡!

 

Winform快速開發平臺系列:

官網鏈接

1.winform快速開發平臺 -> 讓有限的資源創造無限的價值!

2.winform快速開發平臺 -> 基礎組件之分頁控件

3.winform快速開發平臺 -> 綁定ComboBox數據控件

4.winform快速開發平臺 -> 工做流組件(仿GooFlow)

5.winform快速開發平臺 -> 通用權限管理之動態菜單

相關文章
相關標籤/搜索