A DataView is a powerful webpart which provides a larget set of data sources including SharePoint lists, xml files and even web services. A dataview can be fully customized using xslt, for example, to display data in a drop down list instead of data grid. The significant drawback, in my opinion, is that you can add and modify a dataview only through a SharePoint desginer. The problem with using a SharePoint designer for a DataView is that, first of all, it is difficult to deploy a DataView from one environment to another, i.e. from dev server to test, from test to pre-production, from pre-production to production because the datasource that a DataView stores contains GUID of a SharePoint list if a SharePoint list is used as a data source.
Another scenario where using a SharePoint designer is limited is of using a DataView for personal views. Let's say I want to display personalized query for each user using a DataView.
The solution is to create or modify a DataView programmatically. A DataView internally uses a "DataFormWebPart" class.
Here is a code snipet:
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using wsswp = Microsoft.SharePoint.WebPartPages;
using System.Web.UI.WebControls.WebParts;
....
....
....
// Create or Update a DataView programmatically
bool CreateOrUpdateDataViewWebpart(string webUrl, string listName, string pageUrl,
string xslLink,
string zoneName,
string webPartName,
string titleUrl,
bool needsUpdate,
string query,
uint index,
uint maximumRow,
PersonalizationScope personalizationScope
)
{
bool viewCreatedOrUpdated = false;
WebPart wp = null;
wsswp.DataFormWebPart dataFormWebPart = null;
using (SPSite site = new SPSite(webUrl))
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList list = web.Lists[listName];
wsswp.SPLimitedWebPartManager wpManager = web.GetLimitedWebPartManager(pageUrl, personalizationScope);
foreach (WebPart wpTemp in wpManager.WebParts)
{
if (String.Compare(webPartName, wpTemp.Title, true) == 0)
{
wp = wpTemp;
break;
}
}
string dataSourceId = webPartName;
if (wp == null)
{
// Create a webpart
dataFormWebPart = new wsswp.DataFormWebPart();
dataFormWebPart.TitleUrl = titleUrl;
dataFormWebPart.ZoneID = zoneName;
dataFormWebPart.Title = webPartName;
dataFormWebPart.XslLink = xslLink;
SPDataSource dataSource = GetDataSource(dataSourceId, webUrl, list, query, maximumRow);
dataFormWebPart.DataSources.Add(dataSource);
wpManager.AddWebPart(dataFormWebPart, webPartName, index);
viewCreatedOrUpdated = true;
}
else
{
// Update an existing webpart
if (needsUpdate)
{
dataFormWebPart = (wsswp.DataFormWebPart)wp;
dataFormWebPart.TitleUrl = titleUrl;
dataFormWebPart.DataSourceID = string.Empty;
SPDataSource dataSource = GetDataSource(dataSourceId, webUrl, list, query, maximumRow);
dataFormWebPart.DataSources.Clear();
dataFormWebPart.DataSources.Add(dataSource);
wpManager.SaveChanges(dataFormWebPart);
viewCreatedOrUpdated = true;
}
}
return viewCreatedOrUpdated;
}
// Return a SharePoint list filtered by query as a data source
SPDataSource GetDataSource(string dataSourceId, string webUrl, SPList list, string query, uint maximumRow)
{
SPDataSource dataSource = new SPDataSource();
dataSource.UseInternalName = true;
dataSource.ID = dataSourceId;
dataSource.DataSourceMode = SPDataSourceMode.List;
dataSource.List = list;
dataSource.SelectCommand = "<View>" + query + "</View>";
Parameter listIdParam = new Parameter("ListID");
listIdParam.DefaultValue = list.ID.ToString("B").ToUpper();
Parameter maximumRowsParam = new Parameter("MaximumRows");
maximumRowsParam.DefaultValue = maximumRow.ToString();
QueryStringParameter rootFolderParam = new QueryStringParameter("RootFolder", "RootFolder");
dataSource.SelectParameters.Add(listIdParam);
dataSource.SelectParameters.Add(maximumRowsParam);
dataSource.SelectParameters.Add(rootFolderParam);
dataSource.UpdateParameters.Add(listIdParam);
dataSource.DeleteParameters.Add(listIdParam);
dataSource.InsertParameters.Add(listIdParam);
return dataSource;
}
query can be an empty string. the query will contain a SPQuery string contained in "<Query>...</Query>." For example, the full query will look like this:
"<Query><Where><Eq><FieldRef Name='Status'/><Value Type='Text'>Completed</Value></Eq></Where></Query>";
PersonalizationScope will be either PersonalizationScope.Shared or PersonalizationScope.User.