这几个月一直忙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. Casual Note

    20170104 冯诺依曼计算机(遵循冯诺依曼结构设计的计算机:存储器.运算器.控制器.输入设备.输出设备)之前也有计算机,不过在那之前的计算机是专用的,不可编程,只能干特定的事情没法干其他事.与之前 ...

  2. .net core教程

    https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc

  3. sessionState详解

    asp.net Session的默认时间设置是20分钟,即超过20分钟后,服务器会自动放弃Session信息. 当我们在asp.net程序中打开web.config的时候,可以看到一段如下的代码: A ...

  4. HTML5、微信、APP:创业寒冬只能选其一,该选哪个?

    HTML5手机网站 优势:开发技术简单,研发周期短,用户接触成本低 劣势:功能实现相比APP存在差距,用户重复使用难度大,用户粘性差 适合场景:把手机网站当成网络上的“电子产品介绍手册”.手机网站更适 ...

  5. Linux vmstat使用

    Vmstat命令的简单使用 Vmstat命令是Linux/unix常用的系统监控工具,可以方便的查看CPU.内存.swap分区.IO读写等情况. Vmstat常用的参数主要有两个:1.采集的时间间隔 ...

  6. 如何改变span元素的宽度与高度

    内联元素:也称为行内元素,当多个行内元素连续排列时,他们会显示在一行里面. 内联元素的特性:本身是无法设置宽度和高度属性的,但是可以通过CSS样式来控制,达到我们想要的宽度和高度. span举例1: ...

  7. MySQL收藏

    MySQL手册:5.5手册 .5.6手册 cd /usr/local/mysql/bin mysql -uroot -p show processlist;   // 显示系统中正在运行的所有进程 M ...

  8. Mac Pro 日历增强工具 Itsycal

    Mac 自带的日历工具一点也不好用,好在 Itsycal 弥补了这个缺陷,效果图如下: 下载地址:https://www.mowglii.com/itsycal/,下载解压后,把 Itsycal.ap ...

  9. 服务端调用dubbo的方式

    方式1.通过dubbo 方式2.通过spring applicationContext-dubbo.xml 注意引入提供方的接口jar包

  10. mysql 查询表结构

    use information_schema; select column_name, column_type, data_type, is_nullable, column_comment from ...