这几个月一直忙APP的项目,没来得及更新项目,想想该抽出时间整理一下开发思路,跟大家分享,同时也希望得到宝贵的建议。

先说一下我们的权限管理的的设计思路,首先一个企业信息化管理系统一定会用到权限管理, 那么一个动态的菜单在企业信息化管理系统占有一定的分量。

下面介绍我的一些思路。

由于原声的winform界面美观性不够, 系统采用dotnetbar第三方控件来辅助编程。

首先我们看红色方框部分为我们的动态模块功能。这样我们获得到了以下几个信息, 我们需要记录模块功能, 并且需要父子集关系, 那么对应的我们就需要在数据库中建立一张表来维护我们的动态菜单模块。我们举例命名为BaseModuleTabel, 那么会有一下的内容,Id ParentId Name,并且由于需要跟不同的用户有对应的关系, 我们还要建立用户以及菜单的关系表,来维护用户与菜单的权限关系。

这里就不介绍表的设计。我们先来看看在dotnetbar中如何呈现动态菜单逻辑。

我们先从数据库中获取到所有菜单模块。并通过循环便利动态的加载模块按钮。 并添加对应的模块按钮事件,

         /// <summary>
/// 加载菜单
/// </summary>
private void LoadMenu()
{
var parentEntity = _baseModuleBll.Repository().FindEntity("ParentId", ""); var result = _baseModuleBll.GetModuleList().Select(p => new BaseTreeViewMenuModel()
{
Id = p.ModuleId,
ParentId = p.ParentId,
Name = p.FullName,
Class = p.Location,
Namespace = StringHelper.SubFirstChart(p.Location, '.'),
IsForm = p.Target == "iframe"
}).ToList();
RibbonTabItem ribbonTabItemFrist = null;
var rabbonTabItemEntities = result.Where(p => p.ParentId == parentEntity.ModuleId);
foreach (var ribbonTabItemEntity in rabbonTabItemEntities)
{
var ribbonPanel = new RibbonPanel
{
Text = ribbonTabItemEntity.Name,
Dock = DockStyle.Fill
};
var ribbonTabItem = new RibbonTabItem
{
Text = ribbonTabItemEntity.Name,
Panel = ribbonPanel
};
if (ribbonTabItemFrist == null)
ribbonTabItemFrist = ribbonTabItem;
this.ribbonControlMenu.Controls.Add(ribbonPanel);
this.ribbonControlMenu.Items.Add(ribbonTabItem); var ribbonBar = new RibbonBar { Text = ribbonTabItemEntity.Name };
var buttonItemEntities = result.Where(p => p.ParentId == ribbonTabItemEntity.Id);
foreach (var buttonItem in buttonItemEntities.Select(buttonItemEntitiy =>
new ButtonItem("ButtonItem" + buttonItemEntitiy.Name)
{
Text = buttonItemEntitiy.Name,
Tag = buttonItemEntitiy
}))
{
buttonItem.Click += ButtonItem_Click;
ribbonBar.Items.Add(buttonItem);
ribbonPanel.Controls.Add(ribbonBar);
}
}
this.ribbonControlMenu.SelectedRibbonTabItem = ribbonTabItemFrist; } #endregion

当然我们的框架采用了反射机制来实现组件式开发。通常在一个项目里,为了降低耦合度,我一边将模块力度最小话,并将按一定的规则分类, 处理成摸个模块,在我们的系统中并不影响彼此开发的同时, 每个成员都可以独立的去完成自己的小任务, 说句不好听的, 就算是能力很差的新手,开发出来的耦合度极高的代码, 通过这样一种方式,他的影响范围也紧紧在与他的模块内, 并不影响其他模块操作。 仅作为个人的一种方式,当然通过我们的代码生成器,会生成一定的代码规范,这虽然能避免一些, 但起不到决定性的作用。 毕竟每个人的能力也是大不相同的。作为PM我们需要做的就是降低项目整体风险,按照规定的项目周期,制定完善的项目计划,系统模块划分力度越大,项目把控的越高。

下面打开点击模块按钮来,通过反射来实现对各个模块的初始化以及加载。代码效率目前开无太大障碍。当然如果一个模块dll你要弄个几百兆,那我也只能无语了。你的力度相对较小,会跟你反射的时间挂钩的。

         /// <summary>
/// 打开模块菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonItem_Click(object sender, EventArgs e)
{
var isOpened = false;
var buttonItem = (ButtonItem)sender;
var baseTreeViewMenuModel = (BaseTreeViewMenuModel)buttonItem.Tag;
if (baseTreeViewMenuModel == null) return;
if (!baseTreeViewMenuModel.IsForm) return;
if (string.IsNullOrWhiteSpace(baseTreeViewMenuModel.Namespace)) return;
//遍历现有的Tab页面,如果存在,那么设置为选中即可
foreach (var tabitem in
superTabControlContent.Tabs.Cast<SuperTabItem>()
.Where(tabitem => tabitem.Name == "superTabItem" + baseTreeViewMenuModel.Name))
{
superTabControlContent.SelectedTab = tabitem;
isOpened = true;
break;
}
if (isOpened) return;
var dll = Application.StartupPath + "\\" + baseTreeViewMenuModel.Namespace + ".dll";
if (!File.Exists(dll)) return;
var assembly = Assembly.LoadFrom(dll);
var type = assembly.GetType(baseTreeViewMenuModel.Class);
if (type == null) return;
var form = (FormBase)Activator.CreateInstance(type);
form.ModuleId = baseTreeViewMenuModel.Id;
form.FormBorderStyle = FormBorderStyle.None;
form.TopLevel = false;
form.Visible = true;
form.Dock = DockStyle.Fill;
var superTabItem = superTabControlContent.CreateTab(baseTreeViewMenuModel.Name);
superTabItem.Text = baseTreeViewMenuModel.Name;
superTabItem.Name = "superTabItem" + baseTreeViewMenuModel.Name;
superTabItem.AttachedControl.Controls.Add(form);
superTabControlContent.SelectedTab = superTabItem;
} #endregion

通过以上的代码我们就可以实现如下图所示的动态菜单功能 。

分享是美德,要提倡!

Winform快速开发平台系列:

官网连接

1.winform快速开发平台 -> 让有限的资源创造无限的价值!

2.winform快速开发平台 -> 基础组件之分页控件

3.winform快速开发平台 -> 绑定ComboBox数据控件

4.winform快速开发平台 -> 工作流组件(仿GooFlow)

5.winform快速开发平台 -> 通用权限管理之动态菜单

winform快速开发平台 -> 通用权限管理之动态菜单的更多相关文章

  1. winform快速开发平台->让有限的资源创造无限的价值!

    最近一直在维护一套自己的快速开发平台. 主要应对针对C/S架构下的项目.然而对winform这快,还真没有看到过相对好的快速开发平台, 何为快速,在博客园逛了了好久, 预览了很多通用权限管理系统. 确 ...

  2. winform快速开发平台 -> 工作流组件(仿GooFlow)

    对于web方向的工作流,一直在用gooflow对于目前我的winform开发平台却没有较好的工作流组件.  针对目前的项目经验告诉我们.一个工作流控件是很必要的. 当然在winform方面的工作流第三 ...

  3. winform快速开发平台 -> 快速绑定ComboBox数据控件

    通常我们在处理编辑窗体时.往往会遇到数据绑定.例如combobox控件绑定数据字典可能是我们经常用到的.然而在我的winform快速开发平台中我是如何处理这个频繁的操作呢? 首先,我们要绑定combo ...

  4. winform快速开发平台 -> 基础组件之分页控件

    一个项目控件主要由及部分的常用组件,当然本次介绍的是通用分页控件. 处理思想:我们在处理分页过程中主要是针对数据库操作. 一般情况主要是传递一些开始位置,当前页数,和数据总页数以及相关关联的业务逻辑. ...

  5. SNF快速开发平台MVC-名片管理(实际名片样式)

    名片管理实际的做的意义在于演示应用,在这里使用的技术有排序控件,查询条件.自由样式瀑布流式分页等技术. 下面是自由样式效果图: 下面表格样式效果图: 具体操作: 新增名片 在新增时可以上传图像进行裁剪 ...

  6. SNF快速开发平台2019-权限管理模型-记录级-字段级权限实践

    1.1.1  字段级权限 字段级权限适用于对不同人的能否查看或录入不同表不同字段的权限控制. 是否启用字段级权限配置 不启用字段级权限后,[用户权限管理]程序[字段级权限]按钮会隐藏,导致无法给管理其 ...

  7. SNF快速开发平台2019-权限管理模型实践-权限都在这里

    其它权限实践系列文章: 1.角色.权限.账户的概念理解-非常全的理论讲解权限控制 https://www.cnblogs.com/spring_wang/p/10954370.html 2.权限管理模 ...

  8. SNF快速开发平台2019-权限管理模型简介-权限都在这里

    1.1    权限的概念 权限是指为了保证职责的有效履行,任职者必须具备的,对某事项进行决策的范围和程度.它常常用“具有批准……事项的权限”来进行表达.例如,具有批准预算外5000元以内的礼品费支出的 ...

  9. SNF快速开发平台2019-权限管理模型-平台服务(多平台\多组织\SAAS\多系统)

    1.1    不同组织机构 通俗的讲,就是一个集团公司,划分几个区域,每个区域都有什么分公司,每个分公司都有哪些部门一样,哪些部门又有那些子部门等. 当然也可以是外贸公司的全球性客户.合作伙伴的分布情 ...

随机推荐

  1. webpack踩坑之路——图片的路径与打包

    转自:http://www.cnblogs.com/ghost-xyx/p/5812902.html 刚开始用webpack的同学很容易掉进图片打包这个坑里,比如打包出来的图片地址不对或者有的图片并不 ...

  2. [asp.net core] Tag Helpers 简介(转)

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...

  3. 实战动态PDF在线预览及带签名的PDF文件转换

    开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是这个想法,说干就干,实践过程总是艰难的,折腾了3 ...

  4. Java界面设计 Swing(1)

    Java界面设计的用途 开发者可以通过Java SE开发丰富并且强大的具有图形界面的桌面应用程序.也可以设计一些提高效率的工具软件,帮助自己处理机械性工作. Java 的图形界面工具包,可以用于工具类 ...

  5. C++ vector容器find查询函数

    vector< ); //查找1 if ( result == L.end( ) ) //没找到 cout << "No" << endl; else ...

  6. ORACLE_UNQNAME

    之前在自己笔记本win7系统上安装了oracle 11g,当时为了节省资源,没启用EM. 此时查看EM状态: C:\Windows\system32>emctl status dbconsole ...

  7. dubbo实践

    最近公司准备重构内部服务模块,准备使用dubbo,故研究一下. 官方文档:http://alibaba.github.io/dubbo-doc-static/Home-zh.htm 1. 用maven ...

  8. 坑爹的微信支付v3,其实没有那么坑

    http://www.cnblogs.com/zskbll/p/wxpay.html 研究微信开发一年多了,每个新接口,都会第一时间进行研究.微信支付开放很久,一直没机会接触到支付接口,等了好久终于从 ...

  9. JDBC的批处理操作三种方式 pstmt.addBatch()

    package lavasoft.jdbctest; import lavasoft.common.DBToolkit; import java.sql.Connection; import java ...

  10. ASP.NET MVC 5 使用autofac实现DI

    使用Nuget添加Autofac.MVC的引用 启动项设置 注册Controller 注册ModelBinder 注册相关的web abstraction 为View层启用属性注入 为Action F ...