您的位置:首页 > 其它

【原创】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类。

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;}

这个控件的运行效果,请参见:/article/5082495.html

Technorati标签:SharePoint,SaveButton

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐