从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理
从本章开始,主要讲解的是页面中对框架相关功能的调用方法,比如列表页面(又分为有层次感列表和普通列表)、编辑页面、多标签页面等,只要熟悉了这些函数的使用方法,那么开发起来就会很便捷了。
1、如图先创建菜单列表与编辑页面
MenuInfoList.aspx
MenuInfoList.aspx.cs
先上列表页面运行效果图
2、列表页代码说明
在页面中,可以看到这条工具条,我们打开aspx页面,找到<f:Toolbar ID="toolBar" runat="server"></f:Toolbar>标签
1 <f:Toolbar ID="toolBar" runat="server"> 2 <Items> 3 <f:Button ID="ButtonRefresh" runat="server" Text="刷新" Icon="ArrowRefresh" OnClick="ButtonRefresh_Click" CssClass="inline"></f:Button> 4 <f:Button ID="ButtonAdd" runat="server" Text="添加" Icon="Add" OnClick="ButtonAdd_Click"></f:Button> 5 <f:Button ID="ButtonSearch" runat="server" Text="查询" Icon="Magnifier" OnClick="ButtonSearch_Click"></f:Button> 6 <%--<f:Button ID="ButtonEdit" runat="server" Text="编辑" Icon="BulletEdit" OnClick="ButtonEdit_Click" 7 OnClientClick="if(!F('Panel1_Grid1').getSelectionModel().hasSelection()|| F('Panel1_Grid1').getSelectionModel().getCount()>=2){F.alert('您没有选择编辑项或只能选择一项进行编辑!'); return false; }"> 8 </f:Button>--%> 9 <f:Button ID="ButtonSaveAutoSort" runat="server" Text="自动排序" Icon="ArrowJoin" OnClick="ButtonSaveAutoSort_Click" ConfirmTitle="自动排序提示" ConfirmText="是否对所有数据进行自动排序?"></f:Button> 10 <f:Button ID="ButtonSaveSort" runat="server" Text="保存排序" Icon="Disk" OnClick="ButtonSaveSort_Click"></f:Button> 11 <f:Button ID="ButtonDelete" runat="server" Text="删除" Icon="Delete" OnClick="ButtonDelete_Click" ConfirmTitle="删除提示" ConfirmText="是否删除记录?" 12 OnClientClick="if (!F('Panel1_Grid1').getSelectionModel().hasSelection() ) { F.alert('删除时必须选择一条将要删除的记录!'); return false; } if (F('Panel1_Grid1').getSelectionModel().getCount() >= 2) { F.alert('只能选择一条记录进行删除!');return false; }"> 13 </f:Button> 14 </Items> 15 </f:Toolbar>
在里面放置的按键都会在这里显示出来,这个标签的Id必须命名为toolBar,因为在PageBase这个父类的初始化函数OnInit中有下面这段代码,会自动为放在这里的按键进行权限判断处理,检查当前用户是否有对应按键的操作权限,没有操作权限的按键自动禁用掉,这样的话我们在开发时就不用为这些按键权限一个个进行赋值,做这么多麻烦的操作了
(灰白色的为已禁用按键)
1 #region 设置页面按键权限 2 try 3 {4 //定义按键控件 5 Control btnControl = null;6 //找到页面放置按键控件的位置 7 ControlCollection controls = MenuInfoBll.GetInstence().GetControls(this.Controls, "toolBar");8 //逐个读取出来 9 for (int i = 0; i < controls.Count; i++)10 {11 //取出控件 12 btnControl =controls[i];13 //判断是否除了刷新、查询和关闭以外的按键 14 if (btnControl.ID != "ButtonRefresh" && btnControl.ID != "ButtonSearch" && btnControl.ID != "ButtonClose" && btnControl.ID != "ButtonReset")15 {16 //是的话检查该按键当前用户是否有控件权限,没有的话则禁用该按键 17 ((FineUI.Button)btnControl).Enabled = MenuInfoBll.GetInstence().CheckControlPower(this, btnControl.ID);18 }19 }20 }21 catch(Exception) { }22 #endregion
对于表格的绑定也很方便,我们想显示那几列,只要将字段绑定到列表中就可以了,修改字段名称或添加新字段时,只需要对数据层与逻辑层的代码重新一键生成后,不用修改其他代码,这里重新绑定就可以显示出来,非常方便,大家可以试试删除下面代码中的几列或在数据库添加新字段测试一下就明白了。
1 <f:Grid ID="Grid1" Title="菜单列表" EnableFrame="false" EnableCollapse="true" AllowSorting="true" SortField="Depth" SortDirection="ASC" 2 PageSize="15" ShowBorder="true" ShowHeader="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True" DataKeyNames="Id" EnableColumnLines="true" 3 OnPageIndexChange="Grid1_PageIndexChange" OnPreRowDataBound="Grid1_PreRowDataBound" OnRowCommand="Grid1_RowCommand"> 4 <Columns> 5 <f:RowNumberField /> 6 <f:BoundField Width="180px" DataField="Name" DataFormatString="{0}" DataSimulateTreeLevelField="Depth" HeaderText="菜单(页面)名" /> 7 <f:BoundField DataField="Url" HeaderText="访问路径" ExpandUnusedSpace="true" /> 8 <f:TemplateField HeaderText="排序" Width="100px"> 9 <ItemTemplate> 10 <asp:TextBox ID="tbSort" runat="server" Width="50px" Text='<%# Eval("Sort") %>' AutoPostBack="false"></asp:TextBox> 11 </ItemTemplate> 12 </f:TemplateField> 13 <f:LinkButtonField HeaderText="是否显示" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否显示" ColumnID="IsDisplay" CommandName="IsDisplay" /> 14 <f:LinkButtonField HeaderText="是否页面" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否页面" ColumnID="IsMenu" CommandName="IsMenu" /> 15 <f:BoundField DataField="Depth" HeaderText="级别层次" TextAlign="Center" /> 16 <f:LinkButtonField HeaderText="操作" TextAlign="Center" ToolTip="点击修改当前记录" ColumnID="ButtonEdit" CommandName="ButtonEdit" /> 17 </Columns> 18 </f:Grid>
对于列表的事件,在Grid标签中,敲一下空格就会弹出可以使用的事件列表出来,只要绑定对应名称后,在cs文件中添加对应函数就能直接调用,具体大家可以去FineUI官网查看使用例子
列表页中,可以看到<f:Label runat="server" ID="lblSpendingTime" Text=""></f:Label>这个标签,这是用来显示列表执行时间的,只需要放上它就会自动显示列表执行时间:
<f:window>标签是用来处理显示和隐藏弹出编辑窗口用的,大家可以根据需要自己修改编辑宽与高
由于MenuInfoList.aspx.cs必须继承PageBase类,所以我们必须实现Init()与LoadData()这两个函数
在列表页面中,我们需要实现Init()函数,并为当前页面所调用的逻辑层对象与表格对象进行赋值,如下面代码。赋值后不少功能就自动实现了,具体请看后面的演示效果。
1 #region 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值 2 public override voidInit()3 {4 //逻辑对象赋值 5 bll =MenuInfoBll.GetInstence();6 //表格对象赋值 7 grid =Grid1;8 }9 #endregion
由于本列表页面要显示的是有层次感的列表,所以Sort调用的是自定义的代码(有层次感的列表排序必须先用Depth进行升序排序后,再用Sort排序),同时也去掉了列表中点击表头排序的功能(会弄乱层次感列表)
对于表格的绑定、翻页等功能,我们在逻辑层已生成对应的函数了,所以这里直接调用就可以了,bll.BindGrid(Grid1, InquiryCondition(), sortList);这个是专门用于有层次感列表的
为了保持列表的层次感,所以查询条件是直接绑定根级别的菜单
1 #region 加载数据 2 /// <summary>读取数据</summary> 3 public override voidLoadData()4 {5 //设置排序 6 if (sortList == null)7 {8 Sort();9 }10 11 //绑定Grid表格 12 bll.BindGrid(Grid1, InquiryCondition(), sortList);13 }14 15 /// <summary> 16 ///查询条件17 /// </summary> 18 /// <returns></returns> 19 private intInquiryCondition()20 {21 int value = 0;22 23 //选择菜单 24 if (ddlParentId.SelectedValue != "0")25 {26 value =ConvertHelper.Cint0(ddlParentId.SelectedValue);27 }28 returnvalue;29 }30 31 #region 排序 32 /// <summary> 33 ///页面表格绑定排序34 /// </summary> 35 public voidSort()36 {37 //设置排序 38 sortList = new List<string>();39 sortList.Add(MenuInfoTable.Depth + "asc");40 sortList.Add(MenuInfoTable.Sort + "asc");41 }42 #endregion 43 44 #endregion
查询效果图
保存排序与自动排序功能(注意观察菜单名称与排序值的变化)
在cs代码中,可以看到,里面并没有保存排序与自动排序的代码,因为在父类中已对这些常用功能进行了封装,所以我们在实现Init()函数时对逻辑层对象与表格对象进行赋值后,就会自动拥有这些功能
未修改
修改排序值
点击保存排序按键
点击自动排序按键
当然对于有父Id的列表自动排序,无需要编写代码就会自动实现了,而对于没有父Id字段的表,我们就需要重写SaveAutoSort()函数来实现,请看下面重写代码
1 /// <summary> 2 ///保存自动排序3 /// </summary> 4 public override voidSaveAutoSort()5 {6 if (bll == null)7 {8 Alert.ShowInParent("保存失败", "逻辑层对象为null,请联系开发人员给当前页面的逻辑层对象赋值");9 return;10 }11 12 if (bll.UpdateAutoSort(this))13 {14 Alert.ShowInParent("保存成功", "保存自动排序成功", "window.location.reload();");15 }16 else 17 {18 Alert.ShowInParent("保存失败", "保存自动排序失败");19 }20 }
根据需要,还可以在UpdateAutoSort函数中加上不同的参数,来实现不同条件下自动排序的效果
列表属性绑定说明
在列表中,我们可以看到是否显示与是否页面的图像是可以点击的,点一下就可以将其改变,如下图
点击之前
点击之后
这个就是在下面代码中进行绑定的
而更新状态的函数MenuInfoBll.GetInstence().UpdateIsDisplay()、MenuInfoBll.GetInstence().UpdateIsMenu(),我们模板里已经生成了,直接调用即可
最后一列编辑按键,这个根据需要可以放到顶部的工具条里(在前面代码大家可以看到我将其注释了),也可以放到这里来,而放到这里的话,则需要在表格绑定的代码中实现
由于整个权限模块未开发出来,所以我先将按键的权限判断注释掉了(//lbfEdit.Enabled = MenuInfoBll.GetInstence().CheckControlPower(this, "ButtonEdit");)
在Grid点击事件中,打开隐藏的编辑窗口
//打开编辑窗口
Window1.IFrameUrl = "MenuInfoEdit.aspx?Id=" + id + "&" + MenuInfoBll.GetInstence().PageUrlEncryptStringNoKey(id + "");
Window1.Hidden = false; //显示窗口
在上面的Url链接中,我们需要传递两个参数,一个是将要编辑的记录Id,一个是页面加密处理参数,通过MenuInfoBll.GetInstence().PageUrlEncryptStringNoKey(id + "")函数来生成对应的页面加密参数,系统在对密钥进行识别处理时,会按顺序默认对Id、pid、ParentId、Key这几个值做为密钥生成值进行识别,具体大家自行研究一下吧。
而对于工具栏中的按键实现,添加新记录对应的是Add()函数、编辑记录对应的是Edit()函数、删除记录对应的是Delete(),当然工具栏中按键的命名要求必须同上面那几个一样,具体实现这里就不再一一细说,大家直接看代码吧。
由于时间关系,编辑页面代码就不进行解说,大家自己进行研究吧,下面上一张编辑页面运行后的图片
另外,为了由于权限模块未完成,所以将相关的权限判断都注释掉了,等后面完善后再启用。
本次更新,除了修改一些小问题外,也修改了CommonBll.cs类的添加用户访问页面记录函数,以及自定义类UseLogBll.cs类的添加用户操作日志函数,让用户访问页面记录运行起来,当然这个表记录的不至这些访问内容,它还会将用户的增、删、查、改等所有操作都记录下来,下面看看效果图(这个函数会将用户登陆进系统后每一步访问都记录下来,这个要求是来自以前的公司老总,当时做了一个OA系统公司自己用,他看了后就说:OA开发后,如果大家都不登陆不使用那有等于没有,能不能实现通过后端查看,知道大家有没有使用。再然后就多了这个功能,呵呵)
本章内容看起来比较乱,大家最好直接运行解决方案代码,在浏览器中运行查看效果,再结合代码查看可能会容易理解,还有一点要补充的是,本解决方案不包含extjs代码,需要大家自行下载放到根目录里
本文转自 AllEmpty 博客园博客,原文链接:http://www.cnblogs.com/EmptyFS/p/3798936.html,如需转载请自行联系原作者
从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理相关推荐
- 从零开始编写自己的C#框架(1)——前言
记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...
- 从零开始编写自己的C#框架(16)——Web层后端父类
从零开始编写自己的C#框架(16)--Web层后端父类 原文:从零开始编写自己的C#框架(16)--Web层后端父类 本章节讲述的各个类是后端系统的核心之一,涉及到系统安全验证.操作日志记录.页面与按 ...
- 从零开始编写自己的C#框架(17)——Web层后端首页
后端首页是管理员登陆后进入的第一个页面,主要是显示当前登陆用户信息.在线人数.菜单树列表.相关功能按键和系统介绍.让管理员能更方便的找到息想要的内容. 根据不同系统的需要,首页会显示不同的内容,比如显 ...
- 从零开始编写自己的C#框架(8)——后台管理系统功能设计
还是老规矩先吐下槽,在规范的开发过程中,这个时候应该是编写总体设计(概要设计)的时候,不过对于中小型项目来说,过于规范的遵守软件工程,编写太多文档也会拉长进度,一般会将它与详细设计合并到一起来处理,所 ...
- 从零开始编写自己的C#框架(9)——数据库设计与创建
对于千万级与百万级数据库设计是有所区别的,由于本项目是基于中小型软件开发框架来设计,记录量相对会比较少,所以数据库设计时考虑的角度是:与开发相结合:空间换性能:空间换开发效率:减少null异常.... ...
- 从零开始编写自己的C#框架(11)——创建解决方案
从零开始编写自己的C#框架(11)--创建解决方案 参考文章: (1)从零开始编写自己的C#框架(11)--创建解决方案 (2)https://www.cnblogs.com/EmptyFS/p/37 ...
- PHP - 从零开始编写自己的PHP框架 - 学习/实践
1.应用场景 自己动手编写一个框架, 帮助学习思考目前常用框架的架构,更加熟悉PHP脚本语言, 学习理解设计思想, 设计原则, 设计模式. 2.学习/操作 1. 文档 如何用PHP写个优雅的Mock框 ...
- 从零开始编写自己的C#框架(14)——T4模板在逻辑层中的应用(三)
原本关于T4模板原想分5个章节详细解说的,不过因为最近比较忙,也不想将整个系列时间拉得太长,所以就将它们整合在一块了,可能会有很多细节没有讲到,希望大家自己对着代码与模板去研究. 本章代码量会比较大, ...
- 从零开始编写自己的C#框架(27)——什么是开发框架
前言 做为一个程序员,在开发的过程中会发现,有框架同无框架,做起事来是完全不同的概念,关系到开发的效率.程序的健壮.性能.团队协作.后续功能维护.扩展......等方方面面的事情.很多朋友在学习搭建自 ...
最新文章
- 使用vSphere Host Update Utility 4.0升级ESX 3到4.0版本
- Node.js的安装
- Linux学习一:(Bash 常用命令、vim操作、Linux框架目录)
- 全排列及相关扩展算法(六)——全排列最蛋疼的算法:邻位对换法
- JAVA水晶花数_我的世界Java版1.17快照20w45a新增物品详解
- 那些天天都在野外钓鱼的人不上班吗,有收入吗?
- python实用库_python常用库
- Python 39 数据库的数据类型
- python加颜色_python输出带颜色字体实例方法
- 多分类决策树 r语言_R语言——决策树模型的相关可视化
- 【小白学习之路】Java实现简单的飞机大战小游戏
- 火山小视频怎么搬运 | 快手伪原创教程
- 2021年求职秘籍丨如何在 IT 部门找到工作?4个步骤必不可少
- 高级文本编辑器:UltraEdit for Mac
- ESP8266、ESP32和STM32的对比
- 案例5-挖掘微博广告高权重词条
- 净水扫盲,净水器该如何选择?
- 雕刻机主轴电机上配带的刀具通过高速旋转
- Android手电筒(闪光灯)
- 绘图工具推荐之甘特图
热门文章
- c语言小饭店等位就餐程序,C语言程序设计 C语言程序设计 3.C语言程序设计教案全部.doc...
- php禁止代理ip访问_php禁止某ip或ip地址段访问的方法(转载)
- python爬虫经典段子_Python爬虫实战(1):爬取糗事百科段子
- linux 测试vim编译器_软件测试工程师必须要掌握的linux命令
- 同软件多个线程设置不同ip_多线程--面试知识
- java构造器调用构造器_java中构造器内部调用构造器实例详解
- java中什么方法用来清空流_这个真的写的很细,JavaIO中的常用处理流,看完只有10%的人还不懂了...
- 跳转到_301跳转常见问题汇总
- 微信小程序云开发 mysql_微信小程序云开发学习笔记(一)云数据库
- web站点放入html页面,HTML