SharePoint Site Definitions & Connected Web Parts

I’ve seen a number of posts about connecting web parts within site definition, but most of them are either confusing or totall outdated.  I ran into the problem of connecting web parts which are provisioned through a site definition (or feature) while working on a client project.

I asked Andrew Connell about whether he know about a way to connect web parts through the CAML directives, but he didn’t know.  Since I trust him, I decided to move on from that path.  It seems like SharePoint 2003 web part declarations (v2) had a <ConnectionID …> and <Connections …> property which could be set.  Since 2007 move the responsiblity of connecting web parts to the web part manager on the page, this is no longer available to us (as far as I know – please comment if you know a way).  I’ve been using a feature receiver to connect up the web parts, calling the following utility function:


  public static void ConnectWebParts(SPWeb web, PersonalizationScope scope, bool autoCheckout, bool autoCheckin, string url, string providerTitle, string consumerTitle, string providerConnectionPointName, string consumerConnectionPointName)
  {
  SPFile file = web.GetFile(url);
  if (!file.Exists) throw new Exception(string.Format("Could not find file '{0}' while connecting web parts.", url));
  if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
  {
  if (file.CheckedOutBy.ID != web.CurrentUser.ID)
  throw new Exception(string.Format("'{0}' is checked out by a different user. Aborting operation.", url));
  }
  else
  {
  if (!autoCheckout)
  throw new Exception(string.Format("'{0}' is not checked out and auto checkout has not been specified in the feature", url));
  else
  file.CheckOut();
  }
using (SPLimitedWebPartManager mgr = web.GetLimitedWebPartManager(url, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
  {
  Utilities.ConnectWebParts(mgr, providerTitle, consumerTitle, providerConnectionPointName, consumerConnectionPointName);
  }

if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None && autoCheckin)
  file.CheckIn(string.Format("Connected web parts '{0}' and '{1}'", consumerTitle, providerTitle));
  }

public static void ConnectWebParts(SPLimitedWebPartManager mgr, string providerTitle, string consumerTitle, string providerConnectionPointName, string consumerConnectionPointName)
  {
  System.Web.UI.WebControls.WebParts.WebPart providerWebPart = null;
  System.Web.UI.WebControls.WebParts.WebPart consumerWebPart = null;

foreach (System.Web.UI.WebControls.WebParts.WebPart wp in mgr.WebParts)
  {
  if (wp.Title == providerTitle)
  providerWebPart = wp;
  else if (wp.Title == consumerTitle)
  consumerWebPart = wp;

//stop look if we've already found both
  if (providerWebPart != null && consumerWebPart != null)
  break;
  }

if (providerWebPart == null || consumerWebPart == null) throw new Exception("Error while connecting Web Parts: could not find needed web part.");

System.Web.UI.WebControls.WebParts.ProviderConnectionPoint provConn = mgr.GetProviderConnectionPoints(providerWebPart)["default"];
  System.Web.UI.WebControls.WebParts.ConsumerConnectionPoint consConn = mgr.GetConsumerConnectionPoints(consumerWebPart)["default"];

mgr.SPConnectWebParts(providerWebPart,
  provConn,
  consumerWebPart,
  consConn);
  }

And the usage (I’m connecting a web part with the title ArticlePageProvider to a web part titled ShowcaseWebPart):

  public override void FeatureActivated(SPFeatureReceiverProperties properties)
  {
  using (SPWeb web = properties.Feature.Parent as SPWeb)
  {
  Utilities.ConnectWebParts(web, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared,
  true,
  true,
  "Pages/default.aspx",
  "ArticlePageProvider",
  "ShowcaseWebPart",
  "default",
  "default");
}
  }

3 Comments

  • Michael Mationschek
    December 2, 2008 - 4:27 pm | Permalink

    You can connect webparts through a site definition. No need to write any code.

    Just add the webparts, connect them and then open the page with sharepoint designer.

    Copy out the two webpart definitions, add the following two lines to each webpart:
    Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.ListViewWebPart

    HTML Encode each webpart definition using the following tool: http://www.opinionatedgeek.com/DotNet/Tools/HTMLEncode/Encode.aspx

    and then take each encoded definition and put it between your element in your definition

    Voila!

  • Michael Mationschek
    December 2, 2008 - 4:28 pm | Permalink

    Sorry the HTML was stripped out in the previous post. Here are the two lines you need to add:

    <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
    <TypeName>Microsoft.SharePoint.WebPartPages.ListViewWebPart</TypeName>

    Hopefully this shows now

  • doltharz
    September 2, 2010 - 10:19 pm | Permalink

    Thos two lines…

    System.Web.UI.WebControls.WebParts.ProviderConnectionPoint provConn = mgr.GetProviderConnectionPoints(providerWebPart)["default"];
    System.Web.UI.WebControls.WebParts.ConsumerConnectionPoint consConn = mgr.GetConsumerConnectionPoints(consumerWebPart)["default"];

    …should be…

    System.Web.UI.WebControls.WebParts.ProviderConnectionPoint provConn = mgr.GetProviderConnectionPoints(providerWebPart)[providerConnectionPointName];
    System.Web.UI.WebControls.WebParts.ConsumerConnectionPoint consConn = mgr.GetConsumerConnectionPoints(consumerWebPart)[consumerConnectionPointName];

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>