
asp.net中自带了一个非常不错的日历控件,但在其呈现方式上还是稍有欠缺。现在我们用一个小技巧,可以轻松创建一个弹出式日期。自此你再也不用去网上找那个带了很多脚本代码的JS制作的弹出式日期控件了。 实现,方式很简单:只需在页面中加入一点Javascript和一些CSS,就可以制作一个简单的弹出式日期选择器。 其中,.aspx代码如下: <head id="Head1" runat="server"> <title>无标题页</title> <mce:script type="text/javascript" language="javascript"><!-- function displayCalendar() { var datepicker=document.getElementById("datePicker"); datePicker.style.display='block'; } // --></mce:script> <mce:style type="text/css"><!-- #datePicker { display:none; position:absolute; border:solid 2px black; background-color:White; } --></mce:style><style type="text/css" mce_bogus="1"> #datePicker { display:none; position:absolute; border:solid 2px black; background-color:White; } </style> </head> <body> <form id="form1" runat="server"> <asp:Label ID="Label1" runat="server" Text="日期:"></asp:Label> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <img src="client.png" mce_src="client.png" alt="日历" onclick="displayCalendar()" /> <div id="datePicker"> <asp:Calendar ID="Calendar1" runat="server" onselectionchanged="Calendar1_SelectionChanged"></asp:Calendar> </div> <asp:Button ID="Button1" runat="server" Text="Button" /> </form> </body> </html> .aspx.cs代码: protected void Calendar1_SelectionChanged(object sender, EventArgs e) { TextBox1.Text = Calendar1.SelectedDate.ToString("d"); } 效果: 技巧二: 当GridVIew用于呈现一个很多字符串记录,而可以设置的宽度又很有限的话,我们可以利用GridView的ToolTip属性的这个技巧,技巧如下: protected void gv_HistoryRecords_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { if (e.Row.Cells[2].Text.Trim().Length > 7) { e.Row.Cells[2].ToolTip = e.Row.Cells[2].Text; e.Row.Cells[2].Text = e.Row.Cells[2].Text.Substring(0, 6) + "<b>....</b>"; } } } 主要是先先判断字段字符长度是否大于某个设定的值,如果大于这个值,将整个字段值都存入ToolTip属性中,然后截取前多少个字符显示在GridView中即可。 效果: 当然如果,在代码中给ToolTip加些标记,设置一下显示外观,应该会更美观一些! 原文发布时间为:2010-04-10 本文作者:vinoYang 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。
任何系统都离不开权限的管理,有一个好的权限管理模块,不仅使我们的系统操作自如,管理方便,也为系统添加亮点。 l 不同职责的人员,对于系统操作的权限应该是不同的。优秀的业务系统,这是最基本的功能。 l 可以对“组”进行权限分配。对于一个大企业的业务系统来说,如果要求管理员为其下员工逐一分配系统操作权限的话,是件耗时且不够方便的事情。所以,系统中就提出了对“组”进行操作的概念,将权限一致的人员编入同一组,然后对该组进行权限分配。 l 权限管理系统应该是可扩展的。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用,而不是每开发一套管理系统,就要针对权限管理部分进行重新开发。 l 满足业务系统中的功能权限。传统业务系统中,存在着两种权限管理,其一是功能权限的管理,而另外一种则是资源权限的管理,在不同系统之间,功能权限是可以重用的,而资源权限则不能。 针对OA系统的特点,权限说明: 权限 在系统中,权限通过模块+动作来产生,模块就是整个系统中的一个子模块,可能对应一个菜单,动作也就是整个模块中(在B/S系统中也就是一个页面的所有操作,比如“浏览、添加、修改、删除”等)。将模块与之组合可以产生此模块下的所有权限。 权限组 为了更方便的权限的管理,另将一个模块下的所有权限组合一起,组成一个“权限组”,也就是一个模块管理权限,包括所有基本权限操作。比如一个权限组(用户管理),包括用户的浏览、添加、删除、修改、审核等操作权限,一个权限组也是一个权限。 角色 权限的集合,角色与角色之间属于平级关系,可以将基本权限或权限组添加到一个角色中,用于方便权限的分配。 用户组 将某一类型的人、具有相同特征人组合一起的集合体。通过对组授予权限(角色),快速使一类人具有相同的权限,来简化对用户授予权限的繁琐性、耗时性。用户组的划分,可以按职位、项目或其它来实现。用户可以属于某一个组或多个组。 通过给某个人赋予权限,有4种方式(参考飞思办公系统) A. 通过职位 a) 在职位中,职位成员的权限继承当前所在职位的权限,对于下级职位拥有的权限不可继承。 b) 实例中:如前台这个职位,对于考勤查询有权限,则可以通过对前台这个职位设置考勤查询的浏览权,使他们有使用这个对象的权限,然后再设置个,考勤查询权(当然也可以不设置,默认能进此模块的就能查询),则所有前台人员都拥有考勤查询的权利。 B. 通过项目 a) 在项目中,项目成员的权限来自于所在项目的权限,他们同样不能继承下级项目的权限,而对于项目组长,他对项目有全权,对下级项目也一样。 b) 实例中:在项目中,项目成员可以对项目中上传文档,查看本项目的文档,可以通过对项目设置一个对于本项目的浏览权来实现进口,这样每个成员能访问这个项目了,再加上项目文档的上传权和查看文档权即可。 c) 对于组长,因为可以赋予组长一个组长权(组长权是个特殊的权限,它包含其他各种权限的一个权限包),所有组长对于本项目有全权,则项目组长可以对于项目文档查看,审批,删除,恢复等,这些权限对于本项目的下级项目依然有效。 C. 通过角色 a) 角色中的成员继承角色的权限,角色与角色没有上下级关系,他们是平行的。通过角色赋予权限,是指没办法按职位或项目的分类来赋予权限的另一种方式,如:系统管理员,资料备份员… b) 实例中:对于本系统中,全体人员应该默认都有的模块,如我的邮件,我的文档,我的日志,我的考勤……,这些模块系统成员都应该有的,我们建立一个角色为系统默认角色,把所有默认访问的模块的浏览权加入到里面去,则系统成员都能访问这些模块。 D. 直接指定 a) 直接指定是通过对某个人具体指定一项权限,使其有使用这个权限的能力。直接指定是角色指定的一个简化版,为了是在建立像某个项目的组长这种角色时,省略创建角色这一个步骤,使角色不至于过多。 b) 实例中:指定某个项目的组长,把组长权指定给某个人。 针对职位、项目组: 如果用添加新员工,员工调换职位、项目组,满足了员工会自动继承所在职位、项目组的权限,不需要重新分配权限的功能。 用户管理 用户可以属于某一个或多个用户组,可以通过对用户组授权,来对组中的所有用户进行权限的授予。一个用户可以属于多个项目组,或担任多个职位。 授权管理 将一个基本权限或角色授予用户或用户组,使用户或用户组拥有授予权限的字符串,如果角色、职位、项目中存在相同的基本权限,则取其中的一个;如脱离角色、职位、项目组,只是取消用户或用户组的中此角色、职位、项目组所授予的权限。用户所拥有的权限是所有途径授予权限的集合。管理员用户可以查看每个用户的最终权限列表。 权限管理 基本操作权限与权限组(基本操作权限的集合)的管理。 物理数据模型图如下: 根据以上设计思想,权限管理总共需要以下基本表: tb_User:用户信息基本表; tb_Department:部门表; tb_Company:公司表; tb_Module:系统模块表; tb_Action:系统中所有操作的动作表; tb_Permit:由tb_Module与tb_Action两表结合产生的系统基本权限表; tb_Permit_Group:权限组表,将一模块的中的所有权限划分一个权限组中,可以通过权限组授予用户权限; tb_Role:角色表,基本权限的集合。无上级与下级之分; tb_Position:职位表,有上级与下级之分; tb_Project:项目组表, tb_Role_Permit:角色授权表; tb_Postion_Permit:职位授权表; tb_Project_Permit:项目授权表; tb_Project_User:项目成员表,IsLead字段代表此成员为项目组长; tb_Postion_User:职位成员表; tb_User_Permit:用户授权表,用户ID与角色、职位、项目及直接授予的权限串表; 权限的产生: 由tb_Module中的ModuleCode与tb_Action中的ActionCode组成 权限代码PermitCode=ModuleCode+ActionCode。 实例:ModuleCode=0101,ActionCode=01,则PermitCode=010101。 权限值则有ModuleValue与ActionCode组合而成,采用下划线来连接。 实例:ModuleValue=Sys_User,ActionValue=AdD,PermitValue= Sys_User_Add 权限组: 包括一组同一模块下的权限的组合,如管理用户包括基本的权限:添加、删除、修改、查看等,将这些组合起来构成一个用户组——“用户管理”权限组。其它类似。只是为了更方便的查看系统权限与权限的分配。 实例:如管理用户的权限代码为010101à查看用户,010102à添加用户,010103à删除用户,010104à修改用户,010105à审核用户等,将这些基本权限组合起来一个集合而构成了“用户管理”权限组。 角色、职位、项目: 也就是按特定的需要划分一种权限的集合。使用角色授权表、职位授权表、项目授权表来实现。授权表中存放的是权限代码PermitCode,而不是权限组的GroupCode代码。 用户授权: 由用户授权表来实现,用户授权表中的RoleCode、PositionCode、ProjectCode分别是角色表中RoleCode组成的串、职位表PositionCode组成的串、ProjectCode组成的串。与角色授权表中的角色代码RoleCode、职位授权表中PositionCode、项目授权表中的ProjectCode不对应(不是主表与从表之间外键关系)。 从而能够实现了一个用户可以拥有多个角色、多个职位、多个项目的情况。 用户授权表中的PermitCode为直接授权的权限代码串,直接给用户分配权限。 实例: 用户ID为UserId=1的用户权限授权表的记录为: RoleCode=001,003 PostionCode = 001,002 ProjectCode=001,005 PermitCode = 010101,020102 表明此用户拥有两个角色,代码为001和003,并继承这两个角色的权限; 担任两个职位,代码为001与002,并继承两个职位的权限; 属于两个项目组中的成员,项目代码为001与005,并继承两个项目中的权限。 直接指定给用户的权限为010101与010102这两个权限代码的权限 用户权限字符串: 根据用户授权表的角色代码、职位代码、项目代码得到权限字符串及表中直接分配的权限字符串组合成一个用户的所有权限字符串集合。 原文发布时间为:2010-05-25 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。
众所周知,由社区开发的AjaxControlToolkit,为asp.net展现富客户端效果和提高web程序性能带来了很大的帮助。里面有大量的实现各种功能的控件可供直接使用。 PopupControlExtender就是其中的一个。我们称呼其为“弹出控件”。它主要的功能是让asp.net控件打开一个弹出对话框,来显示其他额外的信息或选项。弹出控件可以包含任何内容。特别值得一提的是,弹出控件具备通过Web服务或页面方法取得数据的功能。 根据PopupControlExtender的主要作用和其能取得页面数据的特性,下面我们用它来实现显示详情对话框的功能。(在这之前,我们通常的做法是使用一个Gridview+一个FormView或一个GridView+一个DetailsView)。现在我们只需要一个GridView即可。相关实现如下: 这里一个简单的示例是正在做的一个权限管理中的一个显示资源的页面: .aspx: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Module.aspx.cs" Inherits="Privilege_Module" %> <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %> <!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 runat="server"> <title></title> <mce:style type="text/css"><!-- .imgs { visibility: hidden; } table.result { font-family: 标楷体, 楷体; width: 800px; } td.result { border-bottom: 1px dotted #00f; padding: 4px 0px 4px 8px; } .col1 { width: 100px; text-align: center; } .col2 { width: 180px; text-align: center; } .col3 { width: 50px; text-align: center; } .col4 { text-align: right; } .col5 { text-align: right; } .col6 { text-align: right; } .col7 { text-align: right; } --></mce:style><style type="text/css" mce_bogus="1"> .imgs { visibility: hidden; } table.result { font-family: 标楷体, 楷体; width: 800px; } td.result { border-bottom: 1px dotted #00f; padding: 4px 0px 4px 8px; } .col1 { width: 100px; text-align: center; } .col2 { width: 180px; text-align: center; } .col3 { width: 50px; text-align: center; } .col4 { text-align: right; } .col5 { text-align: right; } .col6 { text-align: right; } .col7 { text-align: right; } </style> </head> <body> <form id="form1" runat="server"> <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"> </ajaxToolkit:ToolkitScriptManager> <div> <asp:MultiView ID="mv_Module" runat="server" ActiveViewIndex="0"> <asp:View ID="View1" runat="server"> <table width="100%"> <tr> <td align="right"> <asp:Button ID="btnNew" runat="server" Text="新增" Width="80px" OnClick="btnNew_Click" /> </td> </tr> </table> <asp:GridView ID="GridView1" runat="server" Width="100%" AutoGenerateColumns="False" DataSourceID="lds_Module" OnRowCommand="GridView1_RowCommand" OnRowCreated="GridView1_RowCreated" DataKeyNames="moduleCode"> <Columns> <asp:TemplateField> <ItemTemplate> <asp:Image ID="Image1" runat="server" ImageUrl="~/Magnifier.gif" /> <ajaxToolkit:PopupControlExtender ID="PopupControlExtender1" runat="server" TargetControlID="Image1" PopupControlID="Panel2" Position="Right" DynamicServiceMethod="GetDetials" DynamicContextKey='<%# Eval("moduleCode") %>' OffsetY="50" DynamicControlID="Panel2"> <Animations> <OnHide> <Sequence> <FadeOut duration="0.2" fps="20" minimumOpacity="0" /> <HideAction Visible="false" /> <StyleAction Attribute="display" Value="none"/> </Sequence> </OnHide> <OnShow> <Sequence> <StyleAction Attribute="display" Value="block"/> <HideAction Visible="true" /> <FadeIn duration="0.2" fps="20" /> </Sequence> </OnShow> </Animations> </ajaxToolkit:PopupControlExtender> </ItemTemplate> <ItemStyle HorizontalAlign="Center" /> </asp:TemplateField> <asp:BoundField DataField="moduleCode" HeaderText="moduleCode" ReadOnly="True" SortExpression="moduleCode" /> <asp:BoundField DataField="name" HeaderText="name" ReadOnly="True" SortExpression="name" /> <asp:CheckBoxField DataField="isMaster" HeaderText="isMaster" ReadOnly="True" SortExpression="isMaster" /> <asp:TemplateField HeaderText="操作"> <ItemTemplate> <asp:LinkButton ID="lbtnDetail" runat="server" CommandName="MyDetail">详情</asp:LinkButton> <asp:LinkButton ID="lbtnModify" runat="server" CommandName="MyModify">修改</asp:LinkButton> <asp:LinkButton ID="lbtnDelete" runat="server" CommandName="MyDelete">删除</asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:LinqDataSource ID="lds_Module" runat="server" ContextTypeName="DTMS.DTMS_PrivilegeDataContext" Select="new (moduleCode, name, linkUrl, isMaster, parentModule, moduleLevel, remark)" TableName="Module"> </asp:LinqDataSource> <asp:Panel ID="Panel2" runat="server" BorderStyle="Solid" BorderColor="#060F40" BorderWidth="2px" BackColor="#ffffcc" ForeColor="#060F40" Width="800px"> kajsdhfkjasf</asp:Panel> </asp:View> 几个关键的属性解释: TargetControlID:要被弹出控件 扩转的控件ID; DynamicContextKey:要传递给Web服务或页面方法的任意字符串值,这里绑定给他资源的编号:moduleCode; DynamicControlID:需要执行了Web服务或页面方法后所回的结果的控件的ID,比如上例,我们将该属性值设为Panel2,因为其根据moduleCode提取完成数据后,显示在表格中,而表格是嵌入在Panel2中的,所以Panel2是数据的接收者。 DynamicServiceMethod:要调用的Web服务方法或页面方法。 如果使用的C#,此方法必须符合下列签名格式: [System.Web.Services.WebMethod] [System.Web.Script.Services.ScriptMethod] public string DynamicServiceMethod(string contextKey) {....} 如果使用的VB.net,此方法必须符合下列签名格式: <System.Web.Services.WebMethod>_ <System.Web.Script.Services.ScriptMethod>_ public Function DynamicServiceMethod(ByVal contextKey As String) As String ..... End Function 备注:Web服务方法的名称不一定叫做:DynamicServiceMethod,您可以使用任意的名称作为此方法的名称,但请记住,参数的名称与类型以及返回值的类型,务必与上述格式完全相同,其他相关属性,不作详细说明(都是易于理解的) .cs: 导入Web服务的命名空间: 为“放大镜”图片设置鼠标移入和鼠标移除属性 WebServices方法,用来从后台获取数据: [WebMethod(Description="返回详情列表")] public static string GetDetials(string contextKey) { try { int mid = Convert.ToInt32(contextKey); StringBuilder strHTML = new StringBuilder(); strHTML.Append("<table border='1' class='result'>"); strHTML.Append("<tr class='result'><td class='col1'>模块编号</td><td class='col2'>模块名称</td><td class='col3'>资源链接</td><td class='col4'>是否首页</td><td class='col5'>父模块编号</td><td class='col6'>模块级别</td><td class='col7'>备注</td></tr>"); DTMS.Module module = DTMS.BLL.PrivilegeManage_BLL.Module_BLL.GetModuleById(mid); strHTML.AppendFormat("<tr class='result'><td class='col1'>{0}</td><td class='col2'>{1}</td><td class='col3'>{2}</td><td class='col4'>{3}</td><td class='col5'>{4}</td><td class='col6'>{5}</td><td class='col7'>{6}</td></tr>", module.moduleCode, module.name, module.linkUrl, module.isMaster, module.parentModule, module.moduleLevel, module.remark); strHTML.Append("</table>"); return strHTML.ToString(); } catch (Exception) { return ""; } } 效果图如下:(放大镜图片是在GridView中的一个模板列中放置的,因为为其设置了鼠标移入移除属性,所以当鼠标移入编号为17的放大镜上时会调用以上GetDetails方法,取得详细数据呈现出来) 注意:如果不设置table的width和用于呈现的Panel2的width可能会显示不出详情,所以,务必设置其宽度。 原文发布时间为:2010-06-13 本文作者:vinoYang 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。
在Select列表中创建的别名不能在Select子句之前执行的子句中使用。实际上,表达式别名甚至不能用于Select列表的其他表达式。该限制是由于SQL的另一个独有的特性,即同时操作(all-at-once operation)。例如,在下面这个Select列表中,计算表达式的逻辑顺序无关紧要,而且具有不确定性: Select c1+1 As e1,c2+1 As e2. 因此,不支持下面这个表达式: Select c1+1 As e1,e1+1 As e2. 你只能在Select列表后面的步骤(如Order By步骤)中使用列的别名。 理解:同时操作(all-at-once operation) 我们在大多数编程环境下,交换两个变量的值,通常会使用一个临时变量: //假设有两个已赋值的int型变量a、b int temp; temp=a; a=b; b=temp; 当然只是通常的做法,你也可以运用逻辑运算符: a = a ^ b; b = b ^ a; a = b ^ a; 或者:b = a + (a = b) * 0; 但,在SQL中交换列值可以使用下面的语句: Update dbo.T1 Set c1=c2,c2=c1; 你应该假设所有操作同时发生,而事实上,在更新完成之前并不会修改表(可以理解为更新过程中表中的记录被锁定),而在计算出所有结果之后替换了现有表中的源数据。 所以,下面的更新语句: Update dbo.T1 Set c1=c1+(Select Max(c1) From dbo.T1); 该更新将影响T1表中的所有行,为C1列加上更新开始时T1中的最大的c1值。此时可以认为更新开始后表中的记录被锁住,数据库在后台处理、计算数据。计算完所有数据之后,将一次性替换所有数据。所以你不用担心最大的c1值会随着操作进行而持续变化,可以理解为操作在瞬间发生了。 原文发布时间为:2011-02-14 本文作者:vinoYang 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。
当一个查询到达数据库引擎时,SQL SERVER执行两个主要的步骤来产生期望的查询结果。第一步是查询编译,它生成查询计划,第二步执行这个查询计划。 SQL SERVER 2005中的查询编译由三个步骤组成:分析、代数化及查询优化。完成这些步骤后,编译器把经过优化的查询计划保存到过程缓存中。在这里,执行引擎把该计划转换为可执行的形式,然后执行其中的步骤以生成查询结果。如果今后再次执行相同的查询或存储过程时,过程缓存已经包含了该计划,则跳过编译步骤,直接重用缓存的计划来执行该查询或存储过程。 关于SQL Server的优化: SQL SERVER并不优化批处理中的每条语句。只优化那些访问表而且可能生成多个执行计划的语句。SQL SERVER优化所有DML(数据操作语言)语句,即SELECT 、DELECT和UPDATE语句。除了DML,其他一些T-SQL语句也会被优化,CREATE INDEX便是其中之一,只有被优化过的语句才会生成查询计划。 关于SQL中的分组: GROUP BY或HAVING之类显式子句并不是使SELECT列表被分组的唯一因素。根据SQL的规定,只要出现绑定到特定列表的聚合函数,即使没有GROUP BY或HAVING子句,也会使SELECT列表分组。下面是一个简单的示例: SELECT c1,MAX(c2) FROM dbo.T1; 这是一个分组SELECT,因为查询中包含了一个MAX聚合。又因为它是一个分组SELECT,在其中使用非聚集的列c1是不合法的,所以该查询不正确。 原文发布时间为:2011-02-16 本文作者:vinoYang 本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。