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快速开发平台 -> 通用权限管理之动态菜单

相关文章
相关标签/搜索