WSS/SharePoint: Create a Custom ListViewWebPart
Posted by Guardian in SharePoint WSS on Wednesday 02 September 2009 at 1:32 PM
The standard ListViewWebPart, while it does a lot of work under the hood, offers quite limited functionalities when it comes to programmatically filter the data: even if you can wire up a filter WebPart that provide multiple values, only the first one will be considered; plus you can set only a single WebPart as the ‘data provider’ for the ListView (and this makes the realization of complex filter very hard).
You can rely on different techniques to accomplish the job:
- using SharePoint designer and create custom pages there (but it’s like hard coding the things and the reusability is minimal).
- you can define a set of views and assign them to different users, but it can be easily done only in MOSS using the Target Audience feature, and you cannot do it in WSS.
- other alternatives I do not know...
I didn’t liked any of these approaches and so I decided to try to customize the ListViewWebPart. You cannot directly inherit from the control (the class itself is marked as ‘sealed’, plus it can use many external resources you never know where they can reside given the structure of SharePoint).
I started the thing trying to use the original control, but there problems in the way it handled the views..that is to work correctly he needs to refers to an existing view in the database, but to apply a custom filter query to that view you have to call for the ‘Update’ method of the view object; if the user do not have the right permission that operation will fail and you’ll have an ‘access denied, log with another user’ (or something similar) error.
To overcome this I decided to create a brand new View object based on the schema of the current view (or the view the user have selected) and to call its RenderAsHtml() method; the result is a WebPart that act as the original ListViewWebPart, but that you can easily filter and customize (even in WSS).
Here’s the code:
[Guid("b7ea3f7d-b260-4ce8-9fd0-3af5aee8e0d6")]
public class CustomListViewWebPart : System.Web.UI.WebControls.WebParts.WebPart
{
#region Properties
private string strSourceList = string.Empty;
private string strViewOfSourceList = string.Empty;
private string strQuery = string.Empty;
/// <summary>
/// The List we are displaying
/// </summary>
[Personalizable(true),
WebBrowsable(),
WebDisplayName("List Name"),
WebDescription("Pass the name of the List to show")]
public string SourceList
{
get
{
return strSourceList;
}
set
{
strSourceList = value;
}
}
/// <summary>
/// The Default View of the list
/// </summary>
[Personalizable(true),
WebBrowsable(),
WebDisplayName("View"),
WebDescription("Pass the name of the View that you want to apply to the List")]
public string ViewOfSourceList
{
get
{
return strViewOfSourceList;
}
set
{
strViewOfSourceList = value;
}
}
/// <summary>
/// a CAML query to filter the object
/// </summary>
/// <remarks>
/// in a later revision we will use one or more filter providers to set this
/// </remarks>
[Personalizable(true),
WebBrowsable(),
WebDisplayName("Query"),
WebDescription("Pass the Filter Query")]
public string FilterQuery
{
get
{
return strQuery;
}
set
{
strQuery = value;
}
}
#endregion
public CustomListViewWebPart()
{
this.ExportMode = WebPartExportMode.All;
}
protected override void CreateChildControls()
{
base.CreateChildControls();
SPWeb web = SPContext.Current.Web;
{
try
{
SPList list = web.Lists[SourceList];
// create the toolbar, actually we cannot hide it, we'll need to extend the webpart and those options
ViewToolBar toolbar = new ViewToolBar();
SPContext context = SPContext.GetContext(this.Context, list.Views[ViewOfSourceList].ID, list.ID, SPContext.Current.Web);
toolbar.RenderContext = context;
Controls.Add(toolbar);
// get a reference to the view we want to use
SPView webPartView = web.Lists[SourceList].Views[ViewOfSourceList];
// create a new view based on the original one and attach the filter query to it
// in this way we do not need to modify/update the original element and
// even a user without updating permissions can use this webpart
XmlDocument domDoc = new XmlDocument();
domDoc.LoadXml(webPartView.SchemaXml);
SPView view = new SPView(list, domDoc);
view.Query = FilterQuery;
// render the view
Literal lbl = new Literal();
lbl.Text = view.RenderAsHtml();
this.Controls.Add(lbl);
}
catch (Exception ex)
{
// todo: have a better way to report errors!
Label lbl = new Label();
lbl.Text = "Error occured: ";
lbl.Text += ex.Message;
this.Controls.Add(lbl);
}
}
}
protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls();
base.Render(writer);
}
}
To use it, just instantiate it on a page and set the ‘List’, ‘View’ and optionally ‘Query’ properties to the right values.
On the next articles of this series I’ll show you how to create custom filters and wire them to an evolved version of this WebPart.

#1 da martin - Saturday March 2010 alle 01:15
Good stuff. Thanks
#2 da WSS/SharePoint: adding filtering capabilities to the CustomListViewWebPart (Current User Filter and others) at Guardians Home - Saturday March 2010 alle 01:15
[...] solve both these problems we can take the code we already wrote for our CustomListViewWebPart (see: WSS/SharePoint: Create a Custom ListViewWebPart) and modify it a bit to add the following [...]
#3 da ashiena - Saturday March 2010 alle 01:15
Hye, I start out with trying to use your solution on http://www.primordialcode.com/index.php/2009/11/06/wss-sharepoint-adding-filtering-capabilities-customlistviewwebpart-filter-chain-fixed/ however, I do not know how to add the code even for this entry. Can you please guide me where to start. I would appreciate it very much. Thank you.
#4 da Guardian - Saturday March 2010 alle 01:15
What is your problem specifically? To use this code you have to create a WebPart project and deploy the custom WebPart in a SP environment. This Web Part enables you to filter, but you need to write additional webparts to pass the filters to this one, there are examples on my blog in the previous articles of this serie. To create a WebPart project you can refer to my second or third post regarding SP on this blog, or you can just google around and look for info on VSeWss (that can automate most of the tasks needed).
#5 da MikkoK - Saturday March 2010 alle 01:15
Hi! Thanks for the create code sample. With this I was able to solve my problem. But you are saying in the code that "create the toolbar, actually we cannot hide it". But if you give the toolbar an visible = false property, you are able to hide the toolbar. It is true that you can't give the ViewToolBar option for the view. Of cource you can add one property for the web part to handel the visibility.