XSLTListViewWebpart in Sharepoint 2010 Uncovered


Successor and much more powerful webpart than Dataform or ListViewWebpart provided in Sharepoint 2010, yes, that’s true.

As mentioned in msdn, it handles view rendering for lists which can be document libraries as well as announcements. As the name suggests, it uses a XSLT i.e transforms for Html rendering. Xml data obtained as per Query and XmlDefinition, explained later, is converted into html using Xslt. It, by default, applies styles [ViewStyles] as provided by Sharepoint.

It provides an option to enable column filtering, sorting, Paging and AJAX as well. Yes, filtering, sorting, Paging can be done async, without whole page refresh using AJAX option.

What’s more? You can even define your own custom xsl defining styles, rendering and you have a data rendered the way you want. Custom xslt can override default templates and thus has a power to completely replace default XSLTs which is rarely needed.

For e.g. Dates to be shown in a particular format or you want to specify custom header names rather than display names defined in a list definition or a view.

Isn’t it powerful from what we had earlier?

Why am i writing this?

In my project, i had a requirement to show latest 5 documents with a More… button at the bottom in a page which had other data as well. It should support sorting, filtering but without paging. And most importantly, to show list data which exists in a different site collection.

Surely this is achievable by writing a custom visual web part and a backend code but how much time does this require? If you are following a layered approach and are following a well-defined architecture :), which you will be as a good coder, it can take a lot of time with a filtering, sorting support. And what if Client demands for Paging later. This usually happens in Agile methodology. Plus why to forget a testing?

This is where XsltListView webpart can be handy, inbuilt webpart, already test proven, just set few properties as per your requirements and you are good to go.

But…

What to set, when, why? If you want to use this webpart and you don’t have knowledge how to use it, I pray to God.

You have now 2 options:

  • Either spend a lot of time yourself, exploring this XsltListViewWebpart, or
  • Refer to this blog :). If not 100% , it will definitely save more than 75% of your efforts in fiddling around

How to use?

Following are the few properties which must be considered when using this webpart:

You can either make use of SharepoingDesigner (SPD) or your skill 🙂 to define XsltListViewWebPart definition declaratively.

This is how your final XsltListViewWebpart definition should look like in an ascx file. Just set properties as per your needs here or in the code behind.
Download Sample XSLTListViewWebPart Declaration


Few things to note in the above declaration:

  • Attributes set on element WebPartPages:XsltListViewWebPart like AutoRefresh, AsyncRefresh, AllowEdit, AllowConnect, AllowHide, SuppressWebPartChrome, UseSQLDataSourcePaging, Title, AllowMinimize, ListUrl

Note: ViewGuid attribute if is set when imported through SPD, remove it and set it from the code behind when sites hosting a list are provisioned programmatically.

Consider a below scenario.Each child site in this case then will have a different view identifier and when set wrongly, will raise an exception even without giving a clue, hard to debug. Believe me. My personal experience.

  • ParameterBindings are useful in sorting, filtering
  • XmlDefinition: This definition is the most important part. This defines :
  1.  a view element – Specifies which all fields should be shown on UI, their order through ViewFields element
  • RowLimit element whose value defines the page size. It has an optional attribute Paged which when set to true enables paging
  • Aggregations element which shows a checkbox in each row depending upon the value of mode attribute
  • ViewStyle element whose ID attribute tells which default style should be applied
  • Toolbar element whose Type attribute when set to None doesn’t show any Add button at the bottom
  • Query element which is useful in defining a default column sorting and filtering

Note: In declaration: FieldRef Name=””  , FieldName should be the static name defined while creating a list. If this doesn’t match, an exception is raised.

  • Xsl element defines templates which can override default templates. You can also provice XslLink rather than defining whole Xsl here.

In the above code, defined template does the custom formatting of DateTime. Have a look at mode attribute value. For all DateTime fields which need custom formatting should have value set as DateTime_body. While applying Xslt, this template will be invoked as per the match attribute value.

For the above definition, template will be invoked for a field\column named PromotionDate. It’s value will be shown in ‘dd MMM yyyy’ format.

How to set WebId, ListId, ViewGuid from code?


using (SPSite rootSiteCollection = new SPSite("SiteUrlGoesHere"))
{
using (SPWeb web = rootSiteCollection.OpenWeb())
{
this.ListModuleDocuments.WebId = web.ID;
moduleDocumentLibrary = web.Lists.TryGetList("DocumentLibraryName");
if (moduleDocumentLibrary == null)
{
Logger.LogError("ErrorMessage");
}
this.ListModuleDocuments.ListId = moduleDocumentLibrary.ID;
this.ListModuleDocuments.ListName = moduleDocumentLibrary.ID.ToString();
this.ListModuleDocuments.ViewGuid = moduleDocumentLibrary.DefaultView.ID.ToString();
}
}

Scenario 1: XsltListViewWebpart reads data from list in a different site\site collection

If this is your requirement and you follow the above steps without setting Toolbar’s RenderContext, you will see a non-informative, wrong exception details on a browser.

What to do now?

Copy n Paste:) Yes, copy the below code, call this code after setting various identifiers.


///
/// Sets the context of Toolbar of XsltListView webpart
/// Module web which has the document library
private void SetToolbarContext(SPWeb web)
{
try
{
// Get hold of the toolbar that renders the new menu items
ViewToolBar toolBar = this.GetPrivatePropertyValue("ToolbarControl");
if (toolBar == null)
{
return;
}
// Create the SPContext object that references the correct SPList, SPView and most importantly..SPWeb
SPContext context = SPContext.GetContext(HttpContext.Current, new Guid(this.ListModuleDocuments.ViewGuid), this.ListModuleDocuments.ListId, web);
// Set the RenderContext of the ToolbarControl
toolBar.RenderContext = context;
}
catch
{
}
}

///
/// Gets the toolbar property
/// A Toolbar of type
/// name of the property
/// Toolbar of type
private T GetPrivatePropertyValue(string name)
{
PropertyInfo propertyInfo = this.ListModuleDocuments.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (propertyInfo == null)
{
throw new ArgumentOutOfRangeException("name", string.Format(CultureInfo.InvariantCulture, "Property {0} was not found in Type {1}", name, this.ListModuleDocuments.GetType().FullName));
}
return (T)propertyInfo.GetValue(this.ListModuleDocuments, null);
}
// Here, ListModuleDocuments is a XsltListViewWebpart ID( reference name)

Building Query in XmlDefinition

Query element defines a CAML query. You can specify all filter criterias, sorting on required columns in a way much similar to sql constructs. It supports the logical operations as well.

If you see, this Query is nothing but a structured XML tree which when built can do data selection, data ordering and grouping within a small time, not requiring a great effort or undestanding.

You can learn more on this msdn article
to understand which all operators are supported. A very nice and explanatory article.

Is Custom Filtering supported?

An answer to this is definitely Yes. Let’s talk about the following scenario:

Page has two data sections (webparts): DWP1 and DWP2. DWP1 shows a tabular data for Task entity which has a TaskName column. DWP2 shows all documents of a document library DL1 by default. This DL1 is a store for all Task entity documents. Thus, DWP1 and DWP2 are connected in a sense that each task row in DWP1 may have some docs in DL1 associated to it.

Another requirement reads, if a user clicks on any TaskName in DWP1, docs in DWP2 should be filtered as per the selected TaskName.

This can be done by setting up an InterConnection b/w the two web parts, i.e. defining InterConnected webparts or  have a custom javascript which does a postback on a TaskName click.

Postback is a necessary but not sufficient step.In a postback event handler, Filter query must be modified to fetch only that selected\clicked Task documents.

How to do this? Simple. Yeah simple as long as you know the way.

Modify Query element in XmlDefinition. XsltListViewWebpart exposes a read\write property named XmlDefinition of type System.String. If you read it intially, it will be same as what you would have declared in ascx file. Now, read the Query > Where element, if exists otherwise add a Where element fulfilling your filter criteria.

You can either read XmlDefinition in an XmlDocument and then do xpath query and manipulation or using String manipulation, change XmDefinition directly.

Do remember that you have to assign modified xml definition back to XmlDefinition property. There you go. XsltListViewWebpart will now handle everything for you and fetch only the required data. It has a good performance as well because it won’t fetch the complete data (all tasks’ documents ) and then apply a filter query. Instead, it is similar to reading the filtered data from MS SQL (store).

I struggled, people kept suggesting other techiniques but not this and i believe nothing can be simpler than this.

Where to find Sharepoint Default XSLTs?
Sharepoint 2010 default transforms files are placed in 14 hive, specifically @
%PROGRAMFILES%\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL

Files to be peeked for understanding:

  • fldtypes.xsl
  • main.xsl
  • internal.xsl
  • vwstyles.xsl

Possible Errors and Exceptions

  • Specified view is invalid

Reason: ViewGuid is set in the declarative section of ascx file. This value doesn’t match with the actual view identifier of a list in that particular web.

Resolution: Remove this attribute and set it from the code behind

  • Value does not fall within the expected range

Reason: This is due to toolbar’s render context being set to current web and not to the web which has a list. Remember, XsltListViewWebpart can show data from a list contained in a different web.

Resolution: Set the Toolbar’s RenderContext as shown in the above code snippet.

References

Download Sample XSLTListViewWebPart Declaration

This article doesn’t tell what you want? Need help? Contact me.

27 thoughts on “XSLTListViewWebpart in Sharepoint 2010 Uncovered”

  1. Hi
    // Get hold of the toolbar that renders the new menu items
    ViewToolBar toolBar = GetPrivatePropertyValue(this.custom_XsltListViewWebPart, “ToolbarControl”);

    Toolbar is always null for the XsltListViewWebPart

    Im trying to do it for crosssitecollection listview (page in one sitecollection list from another sitecollection.)

    I was able to display the list with setting
    custom_XsltListViewWebPart.SetPrivatePropertyValue(“SPList”, list);

    public static class SetParamUsingReflection
    {
    public static void SetPrivatePropertyValue(this object obj, string propName, T val)
    {
    Type t = obj.GetType();
    if (t.GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) == null)
    throw new ArgumentOutOfRangeException(“propName”, string.Format(“Property {0} was not found in Type {1}”, propName, obj.GetType().FullName));
    t.InvokeMember(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, obj, new object[] { val });
    }
    }

    but cant get menu working

    Like

  2. Hi!
    your post has already been a bit useful to me, but I have some more question :
    – SharePoint 2010 embeds the Office-style Ribbon, and I need to know whether the “Elements menu” in ribbon shows up automatically when an element of the list view is selected or if all menu must be added manually (through AJAX or whatever) ?

    The scope of this question, is to create ASP application pages with some WebParts dispaying filtered views.

    Regards,

    Like

Leave a comment