I was provisioning pages programmatically with XsltListViewWebParts and that worked just fine. During testing I noticed that when the webpart was using a view configured for paging, the paging controls did not work properly. After some searching on the net I found some articles and how surprisingly they did not work for me.
These were the articles:
http://dinushaonline.blogspot.nl/2014/01/fix-pagination-not-working-properly-in.html
Scenario:
An Announcement list with 6 items. Created a view called TestPaging with paging set to 5 items.
Paging controls are rendering fine, except when on the last page. The Previous-button is not present, so users cannot page back to previous items.
I have SharePoint 2013 SP1 running and this is my code snippet:
XsltListViewWebPart announcementView = new XsltListViewWebPart(); announcementView.ID = "g_" + announcementViewId.Replace('-', '_'); announcementView.Title = "Team announcements"; announcementView.ListName = announcementList.ID.ToString("B").ToUpper(); announcementView.ViewGuid = announcementList.Views["TestPaging"].ID.ToString("B").ToUpper(); wpmgr.AddWebPart(announcementView, "wpz", 0);
When I tried the wpmgr.SaveChanges() right after the AddWebPart() call I got the NullReferenceException. More time for searching the net was needed. Then I stumbled on this article:
http://sharepoint.stackexchange.com/questions/103227/how-to-add-a-listviewwebpart-by-code
Yep. I have SP1 running.
Then I started ILSpy so I could analyse the SaveChanges code:
public void SaveChanges(WebPart webPart) { System.Guid storageKey = this.WebPartManager.GetStorageKey(webPart); this.WebPartManager.SaveChanges(storageKey); } public Guid GetStorageKey(WebPart webPart) { this.ThrowIfNotOnPage(webPart); return WSSProps.GetStorageKey(webPart, this.AttachedProperties); }
The call to ThrowIfNotOnPage triggered me. While I was adding the webparts to the page using the SPLimitedWebPartManager, the page itself was not yet in a final state. What if I call the SaveChanges() method for the XsltListViewWebParts after the page initially is provisioned? In other words: let’s update the page when the first round of priovisioning is done.
I added the following code and called it after the page was fully provisioned and saved.
private void UpdateAllXsltListViewWebParts(SPWeb web) { try { SPFile welcomePage = web.GetFile(web.RootFolder.WelcomePage); using (SPLimitedWebPartManager wpmgr = welcomePage.GetLimitedWebPartManager(PersonalizationScope.Shared)) { foreach (System.Web.UI.WebControls.WebParts.WebPart wpInstance in wpmgr.WebParts) { if (wpInstance.GetType() == typeof(XsltListViewWebPart)) { wpmgr.SaveChanges(wpInstance); } } } welcomePage.Update(); } catch (Exception e) { //Logging or whatever } }
Worked like a charm now!
Hi Octavie,
I have the same problem when adding a XsltListViewWebPart and wonder how you determine the right time for your method that saves the changes to the webpart.
Thanks for help,
Marc
Hi Marc,
You just provision your page with webparts like before. After saving the page (or even publish it) you call the UpdateAllXsltListViewWebParts method. After saving/publishing is the timing.
Octavie