Paging not correct when XsltListViewWebParts are added on page

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://sharepoint.stackexchange.com/questions/92619/paging-in-xsltlistviewwebpart-is-not-working-perfectly-when-added-programmatical

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.

PagingNotWorking1

PagingNotWorking2

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!

image

Share