For a recent project we had several WebParts (Provider and Consumer webparts) on a page which had to be connected to each other when the page was provisioned by our solution.
Unfortunately this cannot be done within the Module.xml
So I created a method which automatically connects the consumer WebParts to their correct provider WebParts.
To do this I basically used the SPLimitedWebPartManager, ProviderConnectionPoint, ConsumerConnectionPoint and some other nice classes.
The method (warning long block of code)
/// <summary>
/// Connects the web parts on page.
/// </summary>
/// <param name="web">The web.</param>
/// <param name="pageUrl">The page URL.</param>
/// <param name="publish">if set to <c>true</c> [publish].</param>
public static void ConnectWebPartsOnPage(SPWeb web, string pageUrl, bool publish)
{
// get the page from the url
SPFile page = web.GetFile(pageUrl);
// make sure the page exists
if (page.Exists)
{
// if the page is checked out, check it in because then the user can do an rollback
if (page.Level == SPFileLevel.Checkout)
{
page.CheckIn("Page was checked out, needs to be checked in before connecting webparts", SPCheckinType.MinorCheckIn);
}
// check out the page because we are going to do changes on it
page.CheckOut();
// get the webpartmanager for the page
using (Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager mgr = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
try
{
// try to connect the webparts on the page
if (ConnectWebParts(mgr))
{
string checkinComment = "Auto connected WebParts on page";
// webparts are connected so update the page and check it in
page.Update();
page.CheckIn(checkinComment);
if (publish)
{
page.Publish(checkinComment);
page.Approve(checkinComment);
}
}
}
catch (Exception ex)
{
page.UndoCheckOut();
throw ex;
}
}
}
}
/// <summary>
/// Checks if a WebPart connection exists.
/// </summary>
/// <param name="connections">The connections.</param>
/// <param name="provider">The provider.</param>
/// <param name="consumer">The consumer.</param>
/// <returns></returns>
private static bool WebPartConnectionExist(Microsoft.SharePoint.WebPartPages.SPWebPartConnectionCollection connections,
System.Web.UI.WebControls.WebParts.WebPart provider, System.Web.UI.WebControls.WebParts.WebPart consumer)
{
foreach (Microsoft.SharePoint.WebPartPages.SPWebPartConnection conn in connections)
{
if (conn.Provider == provider && conn.Consumer == consumer)
{
return true;
}
}
return false;
}
/// <summary>
/// Connects the web parts.
/// </summary>
/// <param name="manager">The manager.</param>
/// <returns></returns>
private static bool ConnectWebParts(Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager manager)
{
bool connectionMade = false;
// get the webparts on the page
Microsoft.SharePoint.WebPartPages.SPLimitedWebPartCollection webparts = manager.WebParts;
// only continu if there are any webparts
if (webparts.Count > 0)
{
ProviderConnectionPointCollection provColl;
ConsumerConnectionPointCollection consColl;
// walk through all the webparts on the page to find provider webparts
foreach (System.Web.UI.WebControls.WebParts.WebPart providerPart in webparts)
{
// check if the webpart is a Provider webpart
provColl = manager.GetProviderConnectionPoints(providerPart);
if (provColl != null && provColl.Default != null)
{
// walk through all the webparts on the page again now to find the consumer webparts
foreach (System.Web.UI.WebControls.WebParts.WebPart consumerPart in webparts)
{
// first make sure the webpart isn't the provider webpart
if (consumerPart != providerPart)
{
// check if the webpart is a Consumer webpart,
// then make sure the consumer webpart isn't already connected to the provider webpart
// then check if the interface of the consumer webpart is assignable from the interface of the provider webpart
consColl = manager.GetConsumerConnectionPoints(consumerPart);
if (consColl != null && consColl.Default != null
&& !WebPartConnectionExist(manager.SPWebPartConnections, providerPart, consumerPart)
&& consColl.Default.InterfaceType.IsAssignableFrom(provColl.Default.InterfaceType))
{
// connect the webparts
manager.SPConnectWebParts(providerPart, provColl.Default, consumerPart, consColl.Default);
connectionMade = true;
}
}
}
}
}
}
return connectionMade;
}
Sample usage (console application)
try
{
using (SPSite site = new SPSite("http://localhost"))
using (SPWeb web = site.OpenWeb())
{
ConnectWebPartsOnPage(web, "pages/default.aspx", false);
}
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Message:\n{0}\n\nStack:\n{1}\n\n", ex.Message, ex.StackTrace);
}