Dela via


Issue with the WebPartManager class while adding webparts dynamically to a specific webpart zone

Once I got a case in which my customer wanted to create a webpart which will allow them to add some custom webparts to the specific zone in the same page by checking the corresponding check boxes in that webpart. (almost similar to the functionality in IGoogle)

 

It will look like the image below :

WebPartPage1

That "Test" webpart was created as a sample one, you can see that there are 2 check boxes in that custom webpart and if we check the images web part check box then it will add a new imageview webpart to the bottom webpart zone, and if we check the ListView webpart then it will add a list view webpart to the right webpart zone.

 

Now we can see the challenges that I had faced while developing this webpart.

 

First I had implemented this functionality using WebPartManager class, and I found that whenever we add a webpart using the AddWebPart () method of WebPartManager class, it will add the webpart to a specified webpart zone, but if we do page refresh or a post back, will keep the newly added webpart some other webpart zone in the page. Bizarre....

 

After researching more and digging in to this concern, I was able to find out that, whenever we use the AddWebPart() method of the WebPartManager class, the AddWebPart() methods gives the WebPart a random ID and therefore it cannot participate in ViewState management and it is not able to persist the state where we set in a particular zone.

 

After researching more on finding out an alternate way, I was able to add the WebPart to specific zones using SPLimitedWebPartManager class instead of WebPartManager. Here the concern was we have to do a refresh or post back again from the page, then only we can see the newly added WebParts. In order to work around that issue we can reload the page after adding any WebParts to the page.

 

Here is the code snippet. I have hard coded the zone as oWPManager.Zones[3] – right zone;, we can change it based upon our requirement, also here I have tested with the PersoanalizationScope as “Shared”. (This code snippet was for adding an imageview webpart)

 

<code>

        void oLinksWP_CheckedChanged(object sender, EventArgs e)

        {

            if (oChkbxLinksWP.Checked)

            { 

                WebPartZone oWPZone = (System.Web.UI.WebControls.WebParts.WebPartZone)oWPManager.Zones[3];

                int iWPCount = oWPZone.WebParts.Count;

                ImageWebPart objImageWP = new ImageWebPart();

                objImageWP.ID = "imgMyWP2";

                objImageWP.Title = "My Image WP";

                SPWeb oWeb = SPContext.Current.Web;

SPFile oFile = oWeb.GetFile(HttpContext.Current.Request.Url.AbsolutePath.ToString());

                SPLimitedWebPartManager oLWPManager = oFile.GetLimitedWebPartManager(PersonalizationScope.Shared); 

                oLWPManager.AddWebPart(objImageWP, oWPZone.ID.ToString(), iWPCount + 1);

                HttpContext.Current.Response.Redirect(HttpContext.Current.Request.Url.AbsolutePath.ToString()); 

            }           

        }

</code>

 

The basic difference between WebPartManager and & SPLimitedWebPartManager is WebPartManager is getting from the System.Web.UI.WebControls.WebParts namespace, but SPLimitedWebPartManager is from Microsoft.SharePoint.WebPartPages;

 

https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.splimitedwebpartmanager.aspx

 

Happy coding J

Comments