【原创】SharePoint2010的SaveButton如何实现在跳转前给用户以提示[How to implement SaveButton display an alert when Redirect action]
2012-08-30 09:22
561 查看
SharePoint2010的SaveButton控件在保存数据后,会跳转到Url参数中的Source指定的页面,如要没有Source则跳转到List的默认页面。有的时候,需要在保存后能够给用户一个提示再进行跳转,这就要修改SaveButton的默认行为,当然最简单的方式就是继承SaveButton,然后进行客户端方式的跳转。幸运的是,SaveButton并非是定义为sealed的,所以继承是没有问题的,所以我定义了SaveButtonEx类。
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
定义两个属性,定义是否为客户端跳转
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
关键的地方在于能够重写其被Click时候的行为,本质上SaveButton并不是直接继承的Button控件,而是通过在CreateChildControls中包装了Button控件实现的,所以要重写的方法是OnBubbleEvent,而不是OnClick.
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
当然,这里面的大部分代码我只是从反编译的代码中复制过来的.其中涉及到一些internal的private的方法及属性,需要使用反射的方式进行调用。
对于跳转的方法其实就很简单了,就是判断是否为客户端跳转,是的话就注册一段脚本,输出alert以及通过window对象进行跳转。下面是这段代码
下面是反射辅助类的代码
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
这个控件的运行效果,请参见:/article/5082495.html
Technorati标签:SharePoint,SaveButton
publicclassSaveButtonEx:Microsoft.SharePoint.WebControls.SaveButton
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
定义两个属性,定义是否为客户端跳转
///<summary> ///是否是客户端跳转 ///</summary> publicBooleanIsClientRedirect { get; set; } ///<summary> ///跳转前的消息 ///</summary> publicstringRedirectMessage { get; set; }
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
关键的地方在于能够重写其被Click时候的行为,本质上SaveButton并不是直接继承的Button控件,而是通过在CreateChildControls中包装了Button控件实现的,所以要重写的方法是OnBubbleEvent,而不是OnClick.
[SharePointPermission(SecurityAction.Demand,ObjectModel=true)] protectedoverrideboolOnBubbleEvent(objectsource,EventArgse) { boolflag=false; if(eisCommandEventArgs) { CommandEventArgsargs=(CommandEventArgs)e; if(!(args.CommandName=="SaveItem")) { returnflag; } SPListItemlistItem=base.ItemContext.ListItem; SPContentTypecontentType=ReflectorUtils.getPerperty<SPContentType>("ContentType",base.ItemContext); if(((listItem!=null)&&(contentType!=null))&&!ReflectorUtils.getPerperty<bool>("HasExternalDataSource",listItem)) { try { listItem["ContentType"]=contentType.Name; ReflectorUtils.InvokeMethod(listItem,"SetExtraInfo",newobject[]{"ContentTypeId",contentType.Id.ToString(),""}); } catch(ArgumentException) { } } this.Page.Validate(); if(!this.Page.IsValid) { returntrue; } boolflag2=false; EventHandleronSaveHandler=base.ItemContext.FormContext.OnSaveHandler; if(onSaveHandler!=null) { ReflectorUtils.InvokeMethod(typeof(Microsoft.SharePoint.WebControls.SaveButton),null,"ActionBeforeSaveItem",newobject[]{ItemContext}); onSaveHandler(this,EventArgs.Empty); flag2=((ReflectorUtils.getPerperty<object>("FieldValidationFailures",base.ItemContext.FormContext)==null) &&(ReflectorUtils.getPerperty<object>("ItemValidationFailure",base.ItemContext.FormContext)==null)) &&(ReflectorUtils.getPerperty<object>("UniqueFieldsWithDuplicateValues",base.ItemContext.FormContext)==null); } elseif(base.List.BaseTemplate==SPListTemplateType.Survey) { if(ReflectorUtils.getPerperty<object>("NextFieldName",base.ItemContext.FormContext)==null) { ReflectorUtils.InvokeMethod(listItem,"Checkin",null); flag2=true; } elseif(base.ControlMode==SPControlMode.New) { ReflectorUtils.InvokeMethod(listItem,"Checkout",null); flag2=true; } else { flag2=this.SaveItem(); } } else { flag2=this.SaveItem(); } flag=true; if(!flag2) { returnflag; } stringredirectUrl=base.RedirectUrl; ReflectorUtils.setPerperty("InSavePostBack",base.ItemContext,true,null);//这里特别要测试一下会不会有异常 boolneedToCreateWorkSpace=(bool)ReflectorUtils.InvokeMethod(typeof(Microsoft.SharePoint.WebControls.SaveButton),this,"NeedToCreateWorkSpace",newobject[]{}); if(needToCreateWorkSpace) { ReflectorUtils.InvokeMethod(typeof(Microsoft.SharePoint.WebControls.SaveButton),this,"GotoMeetingWorkspaceCreationPage",newobject[]{redirectUrl}); returnflag; } if(!base.ItemContext.IsPopUI) { if(base.ItemContext.List.BaseType==SPBaseType.DocumentLibrary) { SPFilefile=((SPListItem)base.Item).File; if(file!=null) { redirectUrl=file.ServerRelativeUrl; } else { SPFolderfolder=((SPListItem)base.Item).Folder; if(folder!=null) { redirectUrl=folder.ServerRelativeUrl; } else { redirectUrl=ReflectorUtils.getPerperty<string>("RootFolderUrl",base.ItemContext.List); } } } if(!this.IsClientRedirect) { SPUtility.Redirect(redirectUrl,SPRedirectFlags.UseSource,this.Context); } else { this.Context.Response.Write( "<scripttype='text/javascript'>alert('"+this.RedirectMessage+ "');window.location.href='"+redirectUrl+"';</script>"); this.Context.Response.Flush(); this.Context.Response.End(); } returnflag; } if((listItem!=null)&&(listItem.File!=null)) { stringserverRelativeUrl=listItem.File.ServerRelativeUrl; this.Context.Response.Write(string.Format(CultureInfo.InvariantCulture,"<scripttype='text/javascript'>\r\nretVal={{}};\r\nretVal['newFileUrl']=\"{0}\";\r\nwindow.frameElement.commitPopup(retVal);\r\n</script>",newobject[]{serverRelativeUrl})); } else { this.Context.Response.Write("<scripttype='text/javascript'>window.frameElement.commitPopup();</script>"); } this.Context.Response.Flush(); this.Context.Response.End(); } returnflag; }
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
当然,这里面的大部分代码我只是从反编译的代码中复制过来的.其中涉及到一些internal的private的方法及属性,需要使用反射的方式进行调用。
对于跳转的方法其实就很简单了,就是判断是否为客户端跳转,是的话就注册一段脚本,输出alert以及通过window对象进行跳转。下面是这段代码
if(!this.IsClientRedirect) { SPUtility.Redirect(redirectUrl,SPRedirectFlags.UseSource,this.Context); } else { this.Context.Response.Write( "<scripttype='text/javascript'>alert('"+this.RedirectMessage+ "');window.location.href='"+redirectUrl+"';</script>"); this.Context.Response.Flush(); this.Context.Response.End(); }
下面是反射辅助类的代码
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Reflection; namespaceOnly.SPLibraryExtend.Utils { ///<summary> ///反射工具 ///</summary> publicclassReflectorUtils { publicstaticvoidsetField(Typetype,stringfieldName,objecto,objectvalue) { FieldInfofi=type.GetField(fieldName,BindingFlags.Instance|BindingFlags.NonPublic); fi.SetValue(o,value); } publicstaticvoidsetField(stringfieldName,objecto,objectvalue) { setField(o.GetType(),fieldName,o,value); } publicstaticTgetField<T>(Typetype,stringfieldName,objecto) { Tresult=default(T); FieldInfofi=type.GetField(fieldName,BindingFlags.Instance|BindingFlags.NonPublic); result=(T)fi.GetValue(o); returnresult; } publicstaticTgetField<T>(stringfieldName,objecto) { returngetField<T>(o.GetType(),fieldName,o); } ///<summary> ///获取反射的属性 ///</summary> ///<typeparamname="T"></typeparam> ///<paramname="property"></param> ///<paramname="o"></param> ///<returns></returns> publicstaticTgetPerperty<T>(stringproperty,objecto) { Tresult; Typet=o.GetType(); PropertyInfopi=t.GetProperty(property,BindingFlags.GetProperty|BindingFlags.Instance|BindingFlags.NonPublic); result=(T)pi.GetValue(o,null); returnresult; } publicstaticvoidsetPerperty(stringproperty,objecto,objectvalue,object[]index) { Typet=o.GetType(); PropertyInfopi=t.GetProperty(property,BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.SetProperty); pi.SetValue(o,value,index); } publicstaticobjectInvokeMethod(objecttarget,stringmethodName,object[]parameters) { returnInvokeMethod(target.GetType(),target,methodName,parameters); } ///<summary> ///反射调用非重载方法 ///</summary> ///<paramname="t"></param> ///<paramname="target"></param> ///<paramname="methodName"></param> ///<paramname="parameters"></param> ///<returns></returns> publicstaticobjectInvokeMethod(Typet,objecttarget,stringmethodName,object[]parameters) { MethodInfomethod=null; if(target==null) { method=t.GetMethod(methodName,BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static); } else { method=t.GetMethod(methodName,BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance); } varresult=method.Invoke(target,parameters); returnresult; } ///<summary> ///反射调用重载的方法 ///</summary> ///<paramname="t"></param> ///<paramname="target"></param> ///<paramname="methodName"></param> ///<paramname="parameters"></param> ///<paramname="parameterTypes"></param> ///<returns></returns> publicstaticobjectInvokeMethod(Typet,objecttarget,stringmethodName,object[]parameters,Type[]parameterTypes) { MethodInfomethod=null; if(target==null) { method=t.GetMethod(methodName,BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static,Type.DefaultBinder,parameterTypes,null); } else { method=t.GetMethod(methodName,BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance,Type.DefaultBinder,parameterTypes,null); } varresult=method.Invoke(target,parameters); returnresult; } } }
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
这个控件的运行效果,请参见:
Technorati标签:
相关文章推荐
- [android]How to implement an not editable scrollable EditText?(如何实现一个不可编辑的带滚动条的EditText?) .
- 如何实现一个搜索引擎(2):查询索引 How to Implement a Search Engine Part 2: Query Index
- 如何实现一个搜索引擎(3):tf-idf权重 How to Implement a Search Engine Part 3: Ranking tf-idf
- 如何实现在Alert提示框之后跳转页面(笔记)
- How to Save an ARIMA Time Series Forecasting Model in Python (如何在Python中保存ARIMA时间序列预测模型)
- In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?
- 【原创】如何让SharePoint2010的内联代码支持.Net framework 3.5[How to embed inline code in aspx with .net framework 3.5 syntax]
- How to display an empty row when the underlying dataset is empty
- 如何实现一个搜索引擎(1):构建索引 How to Implement a Search Engine Part 1: Create Index
- 实现页面session验证,非法用户将弹出提示框并跳转页面
- How to let FIR open a URL when you click an image
- How to send mail by EMS - 如何实现邮件特快专递
- OpenERP-点击按钮跳转到外部URL(Redirect to external URL by clicking a button)
- MVC-RedirectToAction跳转到其他Area
- 如何关闭ReSharper中的[ Use 'var' ]提示How to Disable C# “var” Recommendation in ReSharper
- How to change the size of the button of an android checkbox?
- VS2005下自定义用户控件 如何实现属性及方法的相关智能提示
- 如何使用Shiro实现不同用户登录成功后跳转到不同主页?
- how to sign an assembly with a strong name & how to create a pair key怎样通过强名给程序集签名以及如何创建钥匙对?
- [HOWTO]ORACLE中如何实现ASC字符串和16进制串互相转换