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


這幾個月一直忙APP的項目,沒來得及更新項目,想想該抽出時間整理一下開發思路,跟大家分享,同時也希望得到寶貴的建議。

先說一下我們的權限管理的的設計思路,首先一個企業信息化管理系統一定會用到權限管理, 那么一個動態的菜單在企業信息化管理系統占有一定的分量。

下面介紹我的一些思路。

由於原聲的winform界面美觀性不夠, 系統采用dotnetbar第三方控件來輔助編程。

首先我們看紅色方框部分為我們的動態模塊功能。這樣我們獲得到了以下幾個信息, 我們需要記錄模塊功能, 並且需要父子集關系, 那么對應的我們就需要在數據庫中建立一張表來維護我們的動態菜單模塊。我們舉例命名為BaseModuleTabel, 那么會有一下的內容,Id ParentId Name,並且由於需要跟不同的用戶有對應的關系, 我們還要建立用戶以及菜單的關系表,來維護用戶與菜單的權限關系。  

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

我們先從數據庫中獲取到所有菜單模塊。並通過循環便利動態的加載模塊按鈕。 並添加對應的模塊按鈕事件,

 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我們需要做的就是降低項目整體風險,按照規定的項目周期,制定完善的項目計划,系統模塊划分力度越大,項目把控的越高。 

下面打開點擊模塊按鈕來,通過反射來實現對各個模塊的初始化以及加載。代碼效率目前開無太大障礙。當然如果一個模塊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快速開發平台 -> 通用權限管理之動態菜單


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM