Binding to Sharepoint List Items (Part 2 of 2)
In the first part of the post we went over binding an SPListItemCollection to a DataGrid for quick'n'dirty binding of Sharepoint list data. The problem with this approach is that extensibility is a problem. To paraphrase the specific request I got: "Remember that webpart where you put the List items in a grid? Now I want you to have the grid show the items from two other sites too".
In our first approach, we would be somewhat screwed - the SPListItemCollection represents items in a single list, and I can't merge several of those to one object. I would have to start writing code to take the data out of my SPListItems and putting them into DataRows and do a lot of dirty work - but luckily Sharepoint does that dirty work for us already:
DataSet allItems = new DataSet();
allItems.Merge (myItems.GetDataTable());
This code effortlessly puts a DataTable (with the same name as our List) into a DataSet - no fuss, no mess.
If I now have several lists with the same name and structure but in different sites, I can run the Merge for each and have them all fit in one nice table, and then bind to them in the usual fashion:
<%# DataBinder.Eval (Container.DataItem, "MyCustomProperty") %>
In my case, I wanted the grid to show the items for the selected site's list and for all its subsites, so a simple recursive function got me a DataTable with all items included:
private DataSet getAllItems (SPWeb web, string listName)
{
DataSet items = new DataSet();
items.Merge (web.Lists[listName].Items.GetDataTable());
foreach (SPWeb subweb in web.Webs)
{
items.Merge(getAllItems(subWeb));
}
return items;
}
Note: For brevity's sake I've omitted try/catch blocks, but don't forget that most SPS collections don't have a Contains function, and collection accesses like web.Lists[] must be protected with try/catch.
A further thing I can do with this approach is add more data - like a computed column - into the table:
private DataSet getItemsWithUrl (SPWeb web, string listName)
{
DataSet items = new DataSet();
SPList list = web.Lists[listName];
string displayUrl = web.Url + "/" + list.Forms[PAGETYPE.PAGE_DISPFORM].Url + "?ID=";
DataTable itemTable = list.Items.GetDataTable();
DataColumn UrlColumn = new DataColumn ("Url", typeof(string), "'" + displayUrl + "' + ID");
itemTable.Columns.Add(UrlColumn);
items.Merge (itemTable);
return items;
}
This variant on the previous function gets the list's default Display Item Form from the Forms collection and builds the URL. The computed column we added concats this base URL to the ID of the item, and presto - we have a link to display the ListItem:
<asp:HyperLink NavigateUrl='<%# DataBinder.Eval (Container.DataItem, "Url") %>'>
<%# DataBinder.Eval (Container.DataItem, "Title") %>
</asp:HyperLink>
I hope this helps to bind Sharepoint to ASP.NET quickly and painlessly. :)
3 Comments
Comments have been disabled for this content.
lose weight pills said
bsKfAi Say, you got a nice blog post.Really looking forward to read more. Awesome.
Whiteboard Marker said
Thanks so much for the blog.Much thanks again.
Bubble Wrap said
This is one awesome post.Much thanks again. Much obliged.