I’m currently working on a project the requires the use of WebParts to allow a user to construct custom reports by dragging and dropping WebParts into WebPartZones. I needed to dynamically create these WebParts on the fly and add them to the page programmatically. I tried to do this by using the standard AddWebPart() method of the WebPartManager control but found that using this method the WebPart doesn’t seem to be added to the page correctly which seems to be because the AddWebPart() methods gives the WebPart a random ID therefore it cannot participate in ViewState management. Furthermore because of the need to add the WebPartZones within the Page OnInit event the WebParts were getting recreated each time the page did a postback.
I searched around the web and found lots of people having the same problem but very little in the way of solutions to the problem. Eventually I stumbled across a forum post that mentioned the WebPartManagerInternals class. The documentation fails to mention exactly how to use this class but contained the following text:
“Isolates into a separate class methods that are used by the WebPartManager control and can be overridden by developers who extend the control, but are rarely needed by page developers.”
It also mentions that the class is a sealed class meaning you cannot derive from it and a quick look in Reflector showed me that it’s contructors were internal. This meant I needed to access the class from within the WebPartManager class.
I created a new DynamicWebPartManager class that derived from WebPartManager and in this class I created a method called AddDynamicWebPart(WebPart webPart, WebPartZone zone) which as you can see accepts a WebPart and a WebPartZone. In this method I called two methods on the Internals property (beware this Internals property DOE’S NOT show up in Intellisense) AddWebPart() which accepts a WebPart and SetZoneID() which tells it which WebPartZone to add the WebPart to.
public class DynamicWebPartManager : WebPartManager
public void AddDynamicWebPart(WebPart webPart, WebPartZone zone)
Now by using this DynamicWebPartManager class on your page instead of the out of the box WebPartManager class you can add WebParts by calling the AddDynamicWebPart() method.
WebPartZone reportZone = new WebPartZone();
reportZone.ID = “reportZone1″
reportZone.HeaderText = “My Report”;
TestTableWebPart webPart = new TestTableWebPart();
webPart.ID = “webPart1″
webPart.Title = “My Report – Table”;