Sunday, March 17, 2013

Define the List View for XsltListViewWebPart

When you add XsltListViewWebPart to your page, you will have needs to define the proper list view for the XsltListViewWebPart.

There are two ways you can define the list view for a XsltListViewWebPart programmatically.

First, you can reference to an existing list view of the list from the XsltListViewWebPart. Second, you can use a reflection to change the SPView object currently associated with the XsltListViewWebPart. This is more or less a hack since SharePoint doesn't expose the list view object as public property.

The first step is to get the XsltListViewWebPart from the page using SPLimitedWebPartManager

SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
if (webPartManager == null)
  return;
 
foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartManager.WebParts)
{
    // Only handle xslt web part
    XsltListViewWebPart xsltwp = wp as XsltListViewWebPart;
    if (xsltwp == null)
        continue;

The second step is to get the list and list view of the list.

 // Get list by listUrl
 // catch invalid list url exception
 try
 {
   list = web.GetList(webServerRelativeUrl + "/" + listUrl);
   view = list.Views[viewName];
 }
 catch (Exception expt)
 {
   EventLogger.LogError("SetXsltWebPartView:" + expt.Message + expt.StackTrace);
 }

The third step is to set and save the list view of the XsltListViewWebPart

// Must set ViewId and ViewGuid at the same time
xsltwp.ViewId = Int32.Parse(view.BaseViewID);
xsltwp.ViewGuid = view.ID.ToString("B");
 
webPartManager.SaveChanges(xsltwp);

This approach may not work for some XsltListViewWebPart, for example I found if the list is External List, this won't work. Another approach is to use reflection to get the "ContextView" property as SPView object and change the SPView object.

PropertyInfo pi = xsltwp.GetType().GetProperty("ContextView"BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
SPView view = (SPView)(pi.GetValue(xsltwp, null));
SetXsltListViewCustodianView(web, view);        
webPartManager.SaveChanges(xsltwp);


public static void SetXsltListViewCustomerView(SPWeb web, SPView view)
{
    //Create view
    //http://sarangasl.blogspot.com/2009/12/create-sharepoint-list-view.html
    string viewQuery = "<OrderBy><FieldRef Name=\"FirstName\" /></OrderBy>";
            
    view.Query = viewQuery;
    view.ViewFields.DeleteAll();
    view.ViewFields.Add("FirstName");
    view.ViewFields.Add("LastName");
    view.ViewFields.Add("JobTitle");
    view.ViewFields.Add("Company");
 
    view.Paged = true;
    view.RowLimit = 3;
    view.DefaultView = true;
 
    view.Update();
}

Happy SharePointing!

2 comments:

  1. Ethan - where are you placing this code? httpmodule or page code? what kind of object is the "file" variable at the beginning of the code? I'm using it in a module but nothing changes. Even if I change the XmlDefinition of the web part, nothign changes. I still see the view defined in my page markup (within SPDesigner)

    ReplyDelete
  2. Thanks man you've saved my day :). Second approach works like a charm in SP2013 for XsltListViewWebParts displaying data from another site

    ReplyDelete