从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理
从本章开始,主要讲解的是页面中对框架相关功能的调用方法,比如列表页面(又分为有层次感列表和普通列表)、编辑页面、多标签页面等,只要熟悉了这些函数的使用方法,那么开发起来就会很便捷了。
1、如图先创建菜单列表与编辑页面
MenuInfoList.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MenuInfoList.aspx.cs" Inherits="Solution.Web.Managers.WebManage.Systems.Powers.MenuInfoList" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>菜单(页面)列表</title>
</head>
<body>
<form id="form1" runat="server">
<f:pagemanager id="PageManager1" runat="server" />
<f:panel id="Panel1" runat="server" title="菜单(页面)列表" enableframe="false" bodypadding="10px"
enablecollapse="True">
<toolbars>
<f:Toolbar ID="toolBar" runat="server">
<Items>
<f:Button ID="ButtonRefresh" runat="server" Text="刷新" Icon="ArrowRefresh" OnClick="ButtonRefresh_Click" CssClass="inline"></f:Button>
<f:Button ID="ButtonAdd" runat="server" Text="添加" Icon="Add" OnClick="ButtonAdd_Click"></f:Button>
<f:Button ID="ButtonSearch" runat="server" Text="查询" Icon="Magnifier" OnClick="ButtonSearch_Click"></f:Button>
<%--<f:Button ID="ButtonEdit" runat="server" Text="编辑" Icon="BulletEdit" OnClick="ButtonEdit_Click"
OnClientClick="if(!F('Panel1_Grid1').getSelectionModel().hasSelection()|| F('Panel1_Grid1').getSelectionModel().getCount()>=2){F.alert('您没有选择编辑项或只能选择一项进行编辑!'); return false; }">
</f:Button>--%>
<f:Button ID="ButtonSaveAutoSort" runat="server" Text="自动排序" Icon="ArrowJoin" OnClick="ButtonSaveAutoSort_Click" ConfirmTitle="自动排序提示" ConfirmText="是否对所有数据进行自动排序?"></f:Button>
<f:Button ID="ButtonSaveSort" runat="server" Text="保存排序" Icon="Disk" OnClick="ButtonSaveSort_Click"></f:Button>
<f:Button ID="ButtonDelete" runat="server" Text="删除" Icon="Delete" OnClick="ButtonDelete_Click" ConfirmTitle="删除提示" ConfirmText="是否删除记录?"
OnClientClick="if (!F('Panel1_Grid1').getSelectionModel().hasSelection() ) { F.alert('删除时必须选择一条将要删除的记录!'); return false; } if (F('Panel1_Grid1').getSelectionModel().getCount() >= 2) { F.alert('只能选择一条记录进行删除!');return false; }">
</f:Button>
</Items>
</f:Toolbar>
</toolbars>
<items>
<f:SimpleForm ID="SimpleForm1" BodyPadding="5px" runat="server" EnableFrame="false" EnableCollapse="true"
ShowBorder="True" ShowHeader="False">
<Items>
<f:DropDownList Label="菜单选择" runat="server" ID="ddlParentId" Width="250px"></f:DropDownList>
</Items>
</f:SimpleForm>
<f:Grid ID="Grid1" Title="菜单列表" EnableFrame="false" EnableCollapse="true" AllowSorting="true" SortField="Depth" SortDirection="ASC"
PageSize="" ShowBorder="true" ShowHeader="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True" DataKeyNames="Id" EnableColumnLines="true"
OnPageIndexChange="Grid1_PageIndexChange" OnPreRowDataBound="Grid1_PreRowDataBound" OnRowCommand="Grid1_RowCommand">
<Columns>
<f:RowNumberField />
<f:BoundField Width="180px" DataField="Name" DataFormatString="{0}" DataSimulateTreeLevelField="Depth" HeaderText="菜单(页面)名" />
<f:BoundField DataField="Url" HeaderText="访问路径" ExpandUnusedSpace="true" />
<f:TemplateField HeaderText="排序" Width="100px">
<ItemTemplate>
<asp:TextBox ID="tbSort" runat="server" Width="50px" Text='<%# Eval("Sort") %>' AutoPostBack="false"></asp:TextBox>
</ItemTemplate>
</f:TemplateField>
<f:LinkButtonField HeaderText="是否显示" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否显示" ColumnID="IsDisplay" CommandName="IsDisplay" />
<f:LinkButtonField HeaderText="是否页面" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否页面" ColumnID="IsMenu" CommandName="IsMenu" />
<f:BoundField DataField="Depth" HeaderText="级别层次" TextAlign="Center" />
<f:LinkButtonField HeaderText="操作" TextAlign="Center" ToolTip="点击修改当前记录" ColumnID="ButtonEdit" CommandName="ButtonEdit" />
</Columns>
</f:Grid>
<f:Label runat="server" ID="lblSpendingTime" Text=""></f:Label>
<f:HiddenField runat="server" ID="SortColumn" Text="Id"></f:HiddenField>
</items>
</f:panel>
<f:window id="Window1" width="480px" height="340px" icon="TagBlue" title="编辑" hidden="True"
enablemaximize="True" closeaction="HidePostBack" onclose="Window1_Close" enablecollapse="true"
runat="server" enableresize="true" bodypadding="5px" enableframe="True" iframeurl="about:blank"
enableiframe="true" enableclose="true" plain="false" ismodal="True" enableconfirmonclose="True">
</f:window>
</form>
</body>
</html>
MenuInfoList.aspx.cs
using System;
using System.Collections.Generic;
using DotNet.Utilities;
using FineUI;
using Solution.DataAccess.DataModel;
using Solution.Logic.Managers;
using Solution.Web.Managers.WebManage.Application; namespace Solution.Web.Managers.WebManage.Systems.Powers
{
public partial class MenuInfoList : PageBase
{
#region Page_Load
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//绑定下拉列表
MenuInfoBll.GetInstence().BandDropDownList(this, ddlParentId); LoadData();
}
}
#endregion #region 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值
public override void Init()
{
//逻辑对象赋值
bll = MenuInfoBll.GetInstence();
//表格对象赋值
grid = Grid1;
}
#endregion #region 加载数据
/// <summary>读取数据</summary>
public override void LoadData()
{
//设置排序
if (sortList == null)
{
Sort();
} //绑定Grid表格
bll.BindGrid(Grid1, InquiryCondition(), sortList);
} /// <summary>
/// 查询条件
/// </summary>
/// <returns></returns>
private int InquiryCondition()
{
int value = ; //选择菜单
if (ddlParentId.SelectedValue != "")
{
value = ConvertHelper.Cint0(ddlParentId.SelectedValue);
}
return value;
} #region 排序
/// <summary>
/// 页面表格绑定排序
/// </summary>
public void Sort()
{
//设置排序
sortList = new List<string>();
sortList.Add(MenuInfoTable.Depth + " asc");
sortList.Add(MenuInfoTable.Sort + " asc");
}
#endregion #endregion #region 列表属性绑定 #region 列表按键绑定——修改列表控件属性
/// <summary>
/// 列表按键绑定——修改列表控件属性
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_PreRowDataBound(object sender, FineUI.GridPreRowEventArgs e)
{
//绑定是否显示状态列
GridRow gr = Grid1.Rows[e.RowIndex];
if (((System.Data.DataRowView)(gr.DataItem)).Row.Table.Rows[e.RowIndex][MenuInfoTable.IsDisplay].ToString() == "")
{
var lbf = Grid1.FindColumn("IsDisplay") as LinkButtonField;
lbf.Icon = Icon.BulletCross;
lbf.CommandArgument = "";
}
else
{
var lbf = Grid1.FindColumn("IsDisplay") as LinkButtonField;
lbf.Icon = Icon.BulletTick;
lbf.CommandArgument = "";
} //绑定是否菜单列
if (((System.Data.DataRowView)(gr.DataItem)).Row.Table.Rows[e.RowIndex][MenuInfoTable.IsMenu].ToString() == "")
{
var lbf = Grid1.FindColumn("IsMenu") as LinkButtonField;
lbf.Icon = Icon.BulletCross;
lbf.CommandArgument = "";
}
else
{
var lbf = Grid1.FindColumn("IsMenu") as LinkButtonField;
lbf.Icon = Icon.BulletTick;
lbf.CommandArgument = "";
} //绑定是否编辑列
var lbfEdit = Grid1.FindColumn("ButtonEdit") as LinkButtonField;
lbfEdit.Text = "编辑";
//lbfEdit.Enabled = MenuInfoBll.GetInstence().CheckControlPower(this, "ButtonEdit");
}
#endregion #region Grid点击事件
/// <summary>
/// Grid点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_RowCommand(object sender, FineUI.GridCommandEventArgs e)
{
GridRow gr = Grid1.Rows[e.RowIndex];
//获取主键ID
object id = gr.DataKeys[]; switch (e.CommandName)
{
case "IsDisplay":
//更新状态
MenuInfoBll.GetInstence().UpdateIsDisplay(this, ConvertHelper.Cint0(id), ConvertHelper.Cint0(e.CommandArgument));
//重新加载
LoadData(); break;
case "IsMenu":
//更新状态
MenuInfoBll.GetInstence().UpdateIsMenu(this, ConvertHelper.Cint0(id), ConvertHelper.Cint0(e.CommandArgument));
//重新加载
LoadData(); break;
case "ButtonEdit":
Window1.IFrameUrl = "MenuInfoEdit.aspx?Id=" + id + "&" + MenuInfoBll.GetInstence().PageUrlEncryptStringNoKey(id + "");
Window1.Hidden = false; break;
}
}
#endregion #endregion #region 添加新记录
/// <summary>
/// 添加新记录
/// </summary>
public override void Add()
{
Window1.IFrameUrl = "MenuInfoEdit.aspx?" + MenuInfoBll.GetInstence().PageUrlEncryptString();
Window1.Hidden = false;
}
#endregion #region 编辑记录
/// <summary>
/// 编辑记录
/// </summary>
public override void Edit()
{
string id = GridViewHelper.GetSelectedKey(Grid1, true); Window1.IFrameUrl = "MenuInfoEdit.aspx?Id=" + id + "&" + MenuInfoBll.GetInstence().PageUrlEncryptStringNoKey(id);
Window1.Hidden = false;
}
#endregion #region 删除记录
/// <summary>
/// 删除记录
/// </summary>
/// <returns></returns>
public override string Delete()
{
//获取要删除的ID
int id = ConvertHelper.Cint0(GridViewHelper.GetSelectedKey(Grid1, true)); //如果没有选择记录,则直接退出
if (id == )
{
return "请选择要删除的记录。";
} try
{
//删除前判断一下
if (MenuInfoBll.GetInstence().Exist(x => x.ParentId == id))
{
return "删除失败,本菜单下面存在子菜单,不能直接删除!";
}
//删除前判断一下
if (PagePowerSignBll.GetInstence().Exist(x => x.MenuInfo_Id == id))
{
return "删除失败,本菜单已绑定有页面控件权限标志,不能直接删除!";
} //删除记录
bll.Delete(this, id); return "删除编号ID为[" + id + "]的数据记录成功。";
}
catch (Exception e)
{
string result = "尝试删除编号ID为[" + id + "]的数据记录失败!"; //出现异常,保存出错日志信息
CommonBll.WriteLog(result, e); return result;
}
}
#endregion }
}
先上列表页面运行效果图
2、列表页代码说明
在页面中,可以看到这条工具条,我们打开aspx页面,找到<f:Toolbar ID="toolBar" runat="server"></f:Toolbar>标签
<f:Toolbar ID="toolBar" runat="server">
<Items>
<f:Button ID="ButtonRefresh" runat="server" Text="刷新" Icon="ArrowRefresh" OnClick="ButtonRefresh_Click" CssClass="inline"></f:Button>
<f:Button ID="ButtonAdd" runat="server" Text="添加" Icon="Add" OnClick="ButtonAdd_Click"></f:Button>
<f:Button ID="ButtonSearch" runat="server" Text="查询" Icon="Magnifier" OnClick="ButtonSearch_Click"></f:Button>
<%--<f:Button ID="ButtonEdit" runat="server" Text="编辑" Icon="BulletEdit" OnClick="ButtonEdit_Click"
OnClientClick="if(!F('Panel1_Grid1').getSelectionModel().hasSelection()|| F('Panel1_Grid1').getSelectionModel().getCount()>=2){F.alert('您没有选择编辑项或只能选择一项进行编辑!'); return false; }">
</f:Button>--%>
<f:Button ID="ButtonSaveAutoSort" runat="server" Text="自动排序" Icon="ArrowJoin" OnClick="ButtonSaveAutoSort_Click" ConfirmTitle="自动排序提示" ConfirmText="是否对所有数据进行自动排序?"></f:Button>
<f:Button ID="ButtonSaveSort" runat="server" Text="保存排序" Icon="Disk" OnClick="ButtonSaveSort_Click"></f:Button>
<f:Button ID="ButtonDelete" runat="server" Text="删除" Icon="Delete" OnClick="ButtonDelete_Click" ConfirmTitle="删除提示" ConfirmText="是否删除记录?"
OnClientClick="if (!F('Panel1_Grid1').getSelectionModel().hasSelection() ) { F.alert('删除时必须选择一条将要删除的记录!'); return false; } if (F('Panel1_Grid1').getSelectionModel().getCount() >= 2) { F.alert('只能选择一条记录进行删除!');return false; }">
</f:Button>
</Items>
</f:Toolbar>
在里面放置的按键都会在这里显示出来,这个标签的Id必须命名为toolBar,因为在PageBase这个父类的初始化函数OnInit中有下面这段代码,会自动为放在这里的按键进行权限判断处理,检查当前用户是否有对应按键的操作权限,没有操作权限的按键自动禁用掉,这样的话我们在开发时就不用为这些按键权限一个个进行赋值,做这么多麻烦的操作了
(灰白色的为已禁用按键)
#region 设置页面按键权限
try
{
//定义按键控件
Control btnControl = null;
//找到页面放置按键控件的位置
ControlCollection controls = MenuInfoBll.GetInstence().GetControls(this.Controls, "toolBar");
//逐个读取出来
for (int i = ; i < controls.Count; i++)
{
//取出控件
btnControl = controls[i];
//判断是否除了刷新、查询和关闭以外的按键
if (btnControl.ID != "ButtonRefresh" && btnControl.ID != "ButtonSearch" && btnControl.ID != "ButtonClose" && btnControl.ID != "ButtonReset")
{
//是的话检查该按键当前用户是否有控件权限,没有的话则禁用该按键
((FineUI.Button)btnControl).Enabled = MenuInfoBll.GetInstence().CheckControlPower(this, btnControl.ID);
}
}
}
catch (Exception) { }
#endregion
对于表格的绑定也很方便,我们想显示那几列,只要将字段绑定到列表中就可以了,修改字段名称或添加新字段时,只需要对数据层与逻辑层的代码重新一键生成后,不用修改其他代码,这里重新绑定就可以显示出来,非常方便,大家可以试试删除下面代码中的几列或在数据库添加新字段测试一下就明白了。
<f:Grid ID="Grid1" Title="菜单列表" EnableFrame="false" EnableCollapse="true" AllowSorting="true" SortField="Depth" SortDirection="ASC"
PageSize="" ShowBorder="true" ShowHeader="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True" DataKeyNames="Id" EnableColumnLines="true"
OnPageIndexChange="Grid1_PageIndexChange" OnPreRowDataBound="Grid1_PreRowDataBound" OnRowCommand="Grid1_RowCommand">
<Columns>
<f:RowNumberField />
<f:BoundField Width="180px" DataField="Name" DataFormatString="{0}" DataSimulateTreeLevelField="Depth" HeaderText="菜单(页面)名" />
<f:BoundField DataField="Url" HeaderText="访问路径" ExpandUnusedSpace="true" />
<f:TemplateField HeaderText="排序" Width="100px">
<ItemTemplate>
<asp:TextBox ID="tbSort" runat="server" Width="50px" Text='<%# Eval("Sort") %>' AutoPostBack="false"></asp:TextBox>
</ItemTemplate>
</f:TemplateField>
<f:LinkButtonField HeaderText="是否显示" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否显示" ColumnID="IsDisplay" CommandName="IsDisplay" />
<f:LinkButtonField HeaderText="是否页面" Icon="BulletCross" TextAlign="Center" ToolTip="点击修改是否页面" ColumnID="IsMenu" CommandName="IsMenu" />
<f:BoundField DataField="Depth" HeaderText="级别层次" TextAlign="Center" />
<f:LinkButtonField HeaderText="操作" TextAlign="Center" ToolTip="点击修改当前记录" ColumnID="ButtonEdit" CommandName="ButtonEdit" />
</Columns>
</f:Grid>
对于列表的事件,在Grid标签中,敲一下空格就会弹出可以使用的事件列表出来,只要绑定对应名称后,在cs文件中添加对应函数就能直接调用,具体大家可以去FineUI官网查看使用例子
列表页中,可以看到<f:Label runat="server" ID="lblSpendingTime" Text=""></f:Label>这个标签,这是用来显示列表执行时间的,只需要放上它就会自动显示列表执行时间:
<f:window>标签是用来处理显示和隐藏弹出编辑窗口用的,大家可以根据需要自己修改编辑宽与高
由于MenuInfoList.aspx.cs必须继承PageBase类,所以我们必须实现Init()与LoadData()这两个函数
在列表页面中,我们需要实现Init()函数,并为当前页面所调用的逻辑层对象与表格对象进行赋值,如下面代码。赋值后不少功能就自动实现了,具体请看后面的演示效果。
#region 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值
public override void Init()
{
//逻辑对象赋值
bll = MenuInfoBll.GetInstence();
//表格对象赋值
grid = Grid1;
}
#endregion
由于本列表页面要显示的是有层次感的列表,所以Sort调用的是自定义的代码(有层次感的列表排序必须先用Depth进行升序排序后,再用Sort排序),同时也去掉了列表中点击表头排序的功能(会弄乱层次感列表)
对于表格的绑定、翻页等功能,我们在逻辑层已生成对应的函数了,所以这里直接调用就可以了,bll.BindGrid(Grid1, InquiryCondition(), sortList);这个是专门用于有层次感列表的
为了保持列表的层次感,所以查询条件是直接绑定根级别的菜单
#region 加载数据
/// <summary>读取数据</summary>
public override void LoadData()
{
//设置排序
if (sortList == null)
{
Sort();
} //绑定Grid表格
bll.BindGrid(Grid1, InquiryCondition(), sortList);
} /// <summary>
/// 查询条件
/// </summary>
/// <returns></returns>
private int InquiryCondition()
{
int value = ; //选择菜单
if (ddlParentId.SelectedValue != "")
{
value = ConvertHelper.Cint0(ddlParentId.SelectedValue);
}
return value;
} #region 排序
/// <summary>
/// 页面表格绑定排序
/// </summary>
public void Sort()
{
//设置排序
sortList = new List<string>();
sortList.Add(MenuInfoTable.Depth + " asc");
sortList.Add(MenuInfoTable.Sort + " asc");
}
#endregion #endregion
查询效果图
保存排序与自动排序功能(注意观察菜单名称与排序值的变化)
在cs代码中,可以看到,里面并没有保存排序与自动排序的代码,因为在父类中已对这些常用功能进行了封装,所以我们在实现Init()函数时对逻辑层对象与表格对象进行赋值后,就会自动拥有这些功能
未修改
修改排序值
点击保存排序按键
点击自动排序按键
当然对于有父Id的列表自动排序,无需要编写代码就会自动实现了,而对于没有父Id字段的表,我们就需要重写SaveAutoSort()函数来实现,请看下面重写代码
/// <summary>
/// 保存自动排序
/// </summary>
public override void SaveAutoSort()
{
if (bll == null)
{
Alert.ShowInParent("保存失败", "逻辑层对象为null,请联系开发人员给当前页面的逻辑层对象赋值");
return;
} if (bll.UpdateAutoSort(this))
{
Alert.ShowInParent("保存成功", "保存自动排序成功", "window.location.reload();");
}
else
{
Alert.ShowInParent("保存失败", "保存自动排序失败");
}
}
根据需要,还可以在UpdateAutoSort函数中加上不同的参数,来实现不同条件下自动排序的效果
列表属性绑定说明
在列表中,我们可以看到是否显示与是否页面的图像是可以点击的,点一下就可以将其改变,如下图
点击之前
点击之后
这个就是在下面代码中进行绑定的
#region 列表属性绑定 #region 列表按键绑定——修改列表控件属性
/// <summary>
/// 列表按键绑定——修改列表控件属性
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_PreRowDataBound(object sender, FineUI.GridPreRowEventArgs e)
{
//绑定是否显示状态列
GridRow gr = Grid1.Rows[e.RowIndex];
if (((System.Data.DataRowView)(gr.DataItem)).Row.Table.Rows[e.RowIndex][MenuInfoTable.IsDisplay].ToString() == "")
{
var lbf = Grid1.FindColumn("IsDisplay") as LinkButtonField;
lbf.Icon = Icon.BulletCross;
lbf.CommandArgument = "";
}
else
{
var lbf = Grid1.FindColumn("IsDisplay") as LinkButtonField;
lbf.Icon = Icon.BulletTick;
lbf.CommandArgument = "";
} //绑定是否菜单列
if (((System.Data.DataRowView)(gr.DataItem)).Row.Table.Rows[e.RowIndex][MenuInfoTable.IsMenu].ToString() == "")
{
var lbf = Grid1.FindColumn("IsMenu") as LinkButtonField;
lbf.Icon = Icon.BulletCross;
lbf.CommandArgument = "";
}
else
{
var lbf = Grid1.FindColumn("IsMenu") as LinkButtonField;
lbf.Icon = Icon.BulletTick;
lbf.CommandArgument = "";
} //绑定是否编辑列
var lbfEdit = Grid1.FindColumn("ButtonEdit") as LinkButtonField;
lbfEdit.Text = "编辑";
//lbfEdit.Enabled = MenuInfoBll.GetInstence().CheckControlPower(this, "ButtonEdit");
}
#endregion #region Grid点击事件
/// <summary>
/// Grid点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_RowCommand(object sender, FineUI.GridCommandEventArgs e)
{
GridRow gr = Grid1.Rows[e.RowIndex];
//获取主键ID
object id = gr.DataKeys[]; switch (e.CommandName)
{
case "IsDisplay":
//更新状态
MenuInfoBll.GetInstence().UpdateIsDisplay(this, ConvertHelper.Cint0(id), ConvertHelper.Cint0(e.CommandArgument));
//重新加载
LoadData(); break;
case "IsMenu":
//更新状态
MenuInfoBll.GetInstence().UpdateIsMenu(this, ConvertHelper.Cint0(id), ConvertHelper.Cint0(e.CommandArgument));
//重新加载
LoadData(); break;
case "ButtonEdit":
Window1.IFrameUrl = "MenuInfoEdit.aspx?Id=" + id + "&" + MenuInfoBll.GetInstence().PageUrlEncryptStringNoKey(id + "");
Window1.Hidden = false; break;
}
}
#endregion #endregion
而更新状态的函数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原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。
发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。
更多内容,敬请观注博客:http://www.cnblogs.com/EmptyFS/
从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理的更多相关文章
- Web层后端权限模块
从零开始编写自己的C#框架(19)——Web层后端权限模块 不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太 ...
- 从零开始编写自己的C#框架(19)——Web层后端权限模块
不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太会写了,有些地方想讲得清晰的话,得用多几倍的文字+实例+变化中的 ...
- 从零开始编写自己的C#框架(1)——前言
记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...
- 从零开始编写自己的C#框架 ---- 系列文章
目录: 从零开始编写自己的C#框架(1)——前言从零开始编写自己的C#框架(2)——开发前的准备工作从零开始编写自己的C#框架(3)——开发规范从零开始编写自己的C#框架(4)——文档编写说明从零开始 ...
- 从零开始编写自己的C#框架(17)——Web层后端首页
后端首页是管理员登陆后进入的第一个页面,主要是显示当前登陆用户信息.在线人数.菜单树列表.相关功能按键和系统介绍.让管理员能更方便的找到息想要的内容. 根据不同系统的需要,首页会显示不同的内容,比如显 ...
- 从零开始编写自己的C#框架(15)——Web层后端登陆功能
对于一个后端管理系统,最重要内容之一的就是登陆页了,无论是安全验证.用户在线记录.相关日志记录.单用户或多用户使用帐号控制等,都是在这个页面进行处理的. 1.在解决方案中创建一个Web项目,并将它设置 ...
- 从零开始编写自己的C#框架(25)——网站部署
导航 1.关掉访问保护 2.发布网站 3.复制网站到服务器 4.添加新网站 5.设置网站访问权限 6.设置文件夹访问权限 7.控制可更新文件夹执行权限 8.设置“应用程序池”.net版本与模式 9.附 ...
- 从零开始编写自己的C#框架(8)——后台管理系统功能设计
还是老规矩先吐下槽,在规范的开发过程中,这个时候应该是编写总体设计(概要设计)的时候,不过对于中小型项目来说,过于规范的遵守软件工程,编写太多文档也会拉长进度,一般会将它与详细设计合并到一起来处理,所 ...
- 从零开始编写自己的C#框架(25)——网站部署 【转】
服务器安全部署文档 目录1. 前言.. 3 2. 部署环境.. 3 2.1 服务器环境信息.. 3 3. 磁盘阵列配置.. 4 4. 安装操作系统.. ...
随机推荐
- StringMVC 中如何做数据校验
步骤一:引入四个jar包 步骤二:注册类型转换器 <context:component-scan base-package="cn.happy.controller"> ...
- 基于本地存储的kvm虚拟机在线迁移
基于本地存储的kvm虚拟机在线迁移 kvm虚拟机迁移分为4种(1)热迁移基于共享存储(2)热迁移基于本地存储(3)冷迁移基于共享存储(4)冷迁移基于本地存储 这里介绍的是基于本地存储的热迁移 动态块迁 ...
- 【初学python】使用python连接mysql数据查询结果并显示
因为测试工作经常需要与后台数据库进行数据比较和统计,所以采用python编写连接数据库脚本方便测试,提高工作效率,脚本如下(python连接mysql需要引入第三方库MySQLdb,百度下载安装) # ...
- ASP.NET从零开始学习EF的增删改查
ASP.NET从零开始学习EF的增删改查 最近辞职了,但是离真正的离职还有一段时间,趁着这段空档期,总想着写些东西,想来想去,也不是很明确到底想写个啥,但是闲着也是够 ...
- JQuery 复制粘贴上传图片插件(textarea 和 tinyMCE)
开源地址:https://github.com/yuezhongxin/paste-upload-image.js 支持 Ctrl+C/Ctrl+V 上传,支持拖拽上传,也支持 QQ/微信截图上传. ...
- 移动应用App测试与质量管理一
测试工程师 基于Html的WebApp测试, 现在一些移动App混Html5 HTML5性能测试 兼容性 整理后的脑图 测试招聘 弱化大量技术考察 看重看问题的高度 看重潜力 测试经验 质量管理 专项 ...
- Oracle 表空间和用户权限管理
一. 表空间 Oracle数据库包含逻辑结构和物理结构. 数据库的物理结构指的是构成数据库的一组操作系统文件. 数据库的逻辑结构是指描述数据组织方式的一组逻辑概念以及它们之间的关系. 表空间是数据库逻 ...
- 【道德经】漫谈实体、对象、DTO及AutoMapper的使用
写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...
- 【腾讯Bugly干货分享】Android进程保活招式大全
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:腾讯——张兴华 目前市面上 ...
- 电商系统中的商品模型的分析与设计—续
前言 在<电商系统中的商品模型的分析与设计>中,对电商系统商品模型有一个粗浅的描述,后来有博友对货品和商品的区别以及属性有一些疑问.我也对此做一些研究,再次简单的对商品模型做一个介 ...