Saturday, April 25, 2009

Adding WebParts programmatically to a WebPartZone

I had a very hard time finding information on the web on how to correctly add Web Parts programmatically to my SharePoint WebPartZone.

It's easy to get all the WebParts that are present in the current Site:

SPContext.Current.Site.GetCatalog(SPListTemplateType.WebPartCatalog

Since this is a normal SharePoint list it is also easy to extract the items, display them etc... Now, given that I have selected the WebPart that I want to add:

SPListItem selectedWebPartListItem = SPContext.Current.Site.GetCatalog(SPListTemplateType.WebPartCatalog).Items.GetItemById(selectedWebPartId);

I need now an instance of SPLimitedWebPartManager (Make sure you take the correct PersonalizationScope):

using (SPLimitedWebPartManager manager = SPContext.Current.Web.GetLimitedWebPartManager(this.Page.Request.Url.ToString(), PersonalizationScope.Shared))
{ ... code ... }

Now my trouble started... I found code to create an instance of the WebPart:

string typeName = selectedWebPartListItem.GetFormattedValue("WebPartTypeName");
string assemblyName = selectedWebPartListItem.GetFormattedValue("WebPartAssembly");
ObjectHandle webPartHandle = Activator.CreateInstance(assemblyName, typeName);
System.Web.UI.WebControls.WebParts.WebPart webPart = (System.Web.UI.WebControls.WebParts.WebPart)webPartHandle.Unwrap();

This looks nice - but is completely the WRONG thing to do!

If you are creating an instance of the WebPart like this, you are completely ignoring the (maybe) individual configuration that is set in the .webpart or .dwp file!

The right and (at least in my environment) working way is to import the WebPart like this:

string fileName = string.Format("{0}/{1}", selectedWebPartListItem.Web.Url, selectedWebPartListItem.File.Url);
XmlUrlResolver xmlResolver = new XmlUrlResolver();
xmlResolver.Credentials = CredentialCache.DefaultCredentials;
XmlTextReader reader = new XmlTextReader(fileName);

string errorMsg;
System.Web.UI.WebControls.WebParts.WebPart webPart = manager.ImportWebPart(reader, out errorMsg);

if (!string.IsNullOrEmpty(errorMsg)) {
// your exception handling goes here
}
else
{
manager.AddWebPart(webPart, _wpManager.Zones[_ddlWebPartZones.SelectedItem.Value].ID, Convert.ToInt32(rowIndex));
}


Post a Comment

Blog Popularty Partners

  ©All Right Reserved.

Back to TOP