Well firstly – I’ve got to say this comes off the back of a great Sharepoint MVP and
collegue of mine Ishai Sagi. Big THANKS
Ishai!!!
Typically my experience with the DataFormWebPart has been through the eyes of Sharepoint
Designer – open pages with webparts on them and looking at the XML configuration of
these parts. It look pretty ugly AND very site/web specific – IDs all over the place
etc etc.
Ishai the wealth of knowledge came up with this solution – by overriding the SetDataSourceProperties method,
you can effectively create a datasource from anywhere!!!! Forgetting the IDs etc that
cause all the pain.
I’ve marked the 2 important lines with (**) in the code.
Big Thanks Ishai!!! Folks he’s always one to watch – lock his blog
in and learn!! 🙂
Ishai mentioned that his code below is purely for educational purposes
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Data;
using System.Xml;
namespace AdvancedQueryWebPart
{
[Guid(“46a8853d-415c-458e-990c-419c12fa04f5”)]
public class AdvancedQueryWebPart
: DataFormWebPart, IWebPart
{
public AdvancedQueryWebPart()
{
this.ExportMode = WebPartExportMode.All;
}
protected override void SetDataSourceProperties()
{
try
{
//
Call a custom function that returns the data you want to show as a data table
DataTable results = GetCustomData();
if (results.Rows.Count
> 0)
{
//
generate xml for selected items
XmlDocument doc = new XmlDocument();
XmlNode root = doc.AppendChild(doc.CreateElement(“Rows”));
foreach (DataRow
row in results.Rows)
{
XmlElement
rowNode = doc.CreateElement(“row”);
foreach (DataColumn
col in row.Table.Columns)
{
string val = row[col].ToString();
XmlAttribute
att = doc.CreateAttribute(col.ColumnName);
att.Value = val;
rowNode.Attributes.Append(att);
}
root.AppendChild(rowNode);
}
//
create an XmlDatasource with the new data, and set it to cache for one second
XmlDataSource ds = new XmlDataSource();
ds.CacheDuration = 1;
ds.Data = doc.InnerXml;
//
bind the web part to the xml
(**) this.DataSource = ds;
(**) this.DataBind(true);
}
else
{
Label noResults = new Label();
noResults.Text = “No
results were found”;
this.Controls.Add(noResults);
}
}
catch (Exception
ex)
{
Label lblError = new Label();
lblError.Text = ex.ToString();
this.Controls.Add(lblError);
}
base.SetDataSourceProperties();
}
private DataTable
GetCustomData()
{
try
{
SPWeb webSite = SPContext.Current.Web;
SPSiteDataQuery query = new SPSiteDataQuery();
//look
only in document libraries
query.Lists = “<Lists
ServerTemplate=\”101\” />”;
//search
for documents that have “Test” in the title
query.Query = @”<Where><Contains><FieldRef
Name=””Title”” /><Value Type=”Text””>Test</Value></Contains></Where>”;
//bring
back the title field of the documents
query.ViewFields = @”<FieldRef
Name=””Title”” Nullable=””TRUE”” /><FieldRef Name=””FileLeafRef”” Nullable=””FALSE””
/>”;
DataTable items = webSite.GetSiteData(query);
return items;
}
catch (Exception
ex)
{
throw new Exception(“There
was a problem querying the site with the query”, ex);
}
}
}
}