AjaxBasePart:一个可以支持Ajax的SharePoint WebPart(不需要在master page中增加SrcriptManager)
介绍了一个非常不错的WebPart。可以支持Ajax和SharePoint。同时,它不需要在master page中增加SrcriptManager。
在AjaxBasePart: Easy ASP.NET 2.0 AJAX Extensions 1.0 and Office SharePoint Server 2007博客中,介绍了一个非常不错的WebPart。可以支持Ajax和SharePoint。同时,它不需要在master page中增加SrcriptManager。
由于该文章中的WebPart继承自的Microsoft.SharePoint.WebPartPages.WebPart,已逐渐被微软不再支持,因此我对其进行了改写。具体程序为:
Code
/// <summary>
/// AjaxBasePart allows Microsoft ASP.NET AJAX Extensions to work within Microsoft Office SharePoint Server 2007 webparts.
/// </summary>
[Guid("ca75deab-76f8-469d-9b3f-4ee2775128d2")]
[XmlRoot(Namespace = "HelloAjaxWebPart.AjaxBasePart")]
[CLSCompliant(false)]
public abstract class AjaxBasePart : System.Web.UI.WebControls.WebParts.WebPart
{
private string _ValidationGroupId;
private ValidationSummary _ErrorContainer;
private ScriptManager _AjaxManager;
public AjaxBasePart()
{
}
/// <summary>
/// Exposes the Page's script manager. The value is not set until after OnInit
/// </summary>
[WebPartStorage(Storage.None)]
public ScriptManager AjaxManager
{
get { return _AjaxManager; }
set { _AjaxManager = value; }
}
/// <summary>
/// Oninit fires before page load. Modifications to the page that are necessary to support Ajax are done here.
/// </summary>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//get the existing ScriptManager if it exists on the page
_AjaxManager = ScriptManager.GetCurrent(this.Page);
if (_AjaxManager == null)
{
//create new ScriptManager and EnablePartialRendering
_AjaxManager = new ScriptManager();
_AjaxManager.EnablePartialRendering = true;
// Fix problem with postbacks and form actions (DevDiv 55525)
Page.ClientScript.RegisterStartupScript(typeof(AjaxBasePart), this.ID, "_spOriginalFormAction = document.forms[0].action;", true);
//tag:"form" att:"onsubmit" val:"return _spFormOnSubmitWrapper()" blocks async postbacks after the first one
//not calling "_spFormOnSubmitWrapper()" breaks all postbacks
//returning true all the time, somewhat defeats the purpose of the _spFormOnSubmitWrapper() which is to block repetitive postbacks, but it allows MS AJAX Extensions to work properly
//its a hack that hopefully has minimal effect
if (this.Page.Form != null)
{
string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (!string.IsNullOrEmpty(formOnSubmitAtt) && formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
//add the ScriptManager as the first control in the Page.Form
//I don't think this actually matters, but I did it to be consistent with how you are supposed to place the ScriptManager when used declaritevly
this.Page.Form.Controls.AddAt(0, _AjaxManager);
}
}
}
/// <summary>
/// Needs to be called to ensure that the ValidationSummary control is registered on the page. Any child web parts will need to have base.CreateChildControls() at the top of their own CreateChildControls override.
/// </summary>
protected override void CreateChildControls()
{
base.CreateChildControls();
if (!this.Controls.Contains(_ErrorContainer))
{
_ValidationGroupId = Guid.NewGuid().ToString();
_ErrorContainer = new ValidationSummary();
_ErrorContainer.ID = "_ErrorContainer";
_ErrorContainer.ValidationGroup = _ValidationGroupId;
_ErrorContainer.BorderStyle = BorderStyle.Solid;
_ErrorContainer.BorderWidth = Unit.Pixel(3);
_ErrorContainer.BorderColor = Color.Red;
this.Controls.Add(_ErrorContainer);
}
}
/// <summary>
/// Used to provide a common way to display errors to the user of the current web part.
/// </summary>
/// <param name="message">Description of the error that occured.</param>
public void RegisterError(string message)
{
if (this.Controls.Contains(_ErrorContainer))
{
//this way of generating a unique control id is used in some of the OOB web parts
int uniqueCounter;
if (Context.Items["GetUniqueControlId"] != null)
{
uniqueCounter = (int)Context.Items["GetUniqueControlId"];
}
else
{
uniqueCounter = 0;
}
uniqueCounter++;
Context.Items["GetUniqueControlId"] = uniqueCounter;
//create a custom validator to register the current error message with the ValidationSummary control
CustomValidator cv = new CustomValidator();
cv.ID = string.Concat("_Error_", uniqueCounter);
cv.ValidationGroup = _ValidationGroupId;
cv.Display = ValidatorDisplay.None;
cv.IsValid = false;
cv.ErrorMessage = message;
this.Controls.Add(cv);
}
else
{
//if RegisterError is called before the CreateChildControls override in AjaxBasePart then transfer the user to an error page using the SPUtility
SPUtility.TransferToErrorPage("The CreateChildControls function of the AjaxBasePart has not been called. You probably need to add \"base.CreateChildControls()\" to the top of your CreateChildControls override.");
}
}
}
/// <summary>
/// AjaxBasePart allows Microsoft ASP.NET AJAX Extensions to work within Microsoft Office SharePoint Server 2007 webparts.
/// </summary>
[Guid("ca75deab-76f8-469d-9b3f-4ee2775128d2")]
[XmlRoot(Namespace = "HelloAjaxWebPart.AjaxBasePart")]
[CLSCompliant(false)]
public abstract class AjaxBasePart : System.Web.UI.WebControls.WebParts.WebPart
{
private string _ValidationGroupId;
private ValidationSummary _ErrorContainer;
private ScriptManager _AjaxManager;
public AjaxBasePart()
{
}
/// <summary>
/// Exposes the Page's script manager. The value is not set until after OnInit
/// </summary>
[WebPartStorage(Storage.None)]
public ScriptManager AjaxManager
{
get { return _AjaxManager; }
set { _AjaxManager = value; }
}
/// <summary>
/// Oninit fires before page load. Modifications to the page that are necessary to support Ajax are done here.
/// </summary>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//get the existing ScriptManager if it exists on the page
_AjaxManager = ScriptManager.GetCurrent(this.Page);
if (_AjaxManager == null)
{
//create new ScriptManager and EnablePartialRendering
_AjaxManager = new ScriptManager();
_AjaxManager.EnablePartialRendering = true;
// Fix problem with postbacks and form actions (DevDiv 55525)
Page.ClientScript.RegisterStartupScript(typeof(AjaxBasePart), this.ID, "_spOriginalFormAction = document.forms[0].action;", true);
//tag:"form" att:"onsubmit" val:"return _spFormOnSubmitWrapper()" blocks async postbacks after the first one
//not calling "_spFormOnSubmitWrapper()" breaks all postbacks
//returning true all the time, somewhat defeats the purpose of the _spFormOnSubmitWrapper() which is to block repetitive postbacks, but it allows MS AJAX Extensions to work properly
//its a hack that hopefully has minimal effect
if (this.Page.Form != null)
{
string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (!string.IsNullOrEmpty(formOnSubmitAtt) && formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
//add the ScriptManager as the first control in the Page.Form
//I don't think this actually matters, but I did it to be consistent with how you are supposed to place the ScriptManager when used declaritevly
this.Page.Form.Controls.AddAt(0, _AjaxManager);
}
}
}
/// <summary>
/// Needs to be called to ensure that the ValidationSummary control is registered on the page. Any child web parts will need to have base.CreateChildControls() at the top of their own CreateChildControls override.
/// </summary>
protected override void CreateChildControls()
{
base.CreateChildControls();
if (!this.Controls.Contains(_ErrorContainer))
{
_ValidationGroupId = Guid.NewGuid().ToString();
_ErrorContainer = new ValidationSummary();
_ErrorContainer.ID = "_ErrorContainer";
_ErrorContainer.ValidationGroup = _ValidationGroupId;
_ErrorContainer.BorderStyle = BorderStyle.Solid;
_ErrorContainer.BorderWidth = Unit.Pixel(3);
_ErrorContainer.BorderColor = Color.Red;
this.Controls.Add(_ErrorContainer);
}
}
/// <summary>
/// Used to provide a common way to display errors to the user of the current web part.
/// </summary>
/// <param name="message">Description of the error that occured.</param>
public void RegisterError(string message)
{
if (this.Controls.Contains(_ErrorContainer))
{
//this way of generating a unique control id is used in some of the OOB web parts
int uniqueCounter;
if (Context.Items["GetUniqueControlId"] != null)
{
uniqueCounter = (int)Context.Items["GetUniqueControlId"];
}
else
{
uniqueCounter = 0;
}
uniqueCounter++;
Context.Items["GetUniqueControlId"] = uniqueCounter;
//create a custom validator to register the current error message with the ValidationSummary control
CustomValidator cv = new CustomValidator();
cv.ID = string.Concat("_Error_", uniqueCounter);
cv.ValidationGroup = _ValidationGroupId;
cv.Display = ValidatorDisplay.None;
cv.IsValid = false;
cv.ErrorMessage = message;
this.Controls.Add(cv);
}
else
{
//if RegisterError is called before the CreateChildControls override in AjaxBasePart then transfer the user to an error page using the SPUtility
SPUtility.TransferToErrorPage("The CreateChildControls function of the AjaxBasePart has not been called. You probably need to add \"base.CreateChildControls()\" to the top of your CreateChildControls override.");
}
}
}