In a number of previous articles I wrote about SharePoint filter webparts. In the first part I introduced 2 custom webparts, a filter provider and a filter consumers. I described how to write the webparts and how to setup the connection between them in your webpart code. In the second article I showed how to use a different type of connection between the provider and the consumer. Instead of providing a filter value, our provider provided a default value for the consumer. In this article I will show how you can add the provider and consumer webparts to SharePoint pages in code. I will also show how to connect them. In the last part I will show how you can add and connect these webparts directly in the page layout. I also looked at adding them from the site definition (onet.xml). I succeeded in adding them, but connecting them from onet.xml didn't work out (yet?).
Step 1 - Initialization
// Initialize
string providerName = "Filter Provider";
string consumerName = "Filter Consumer";
string webName = "http://office2007:300/tc";
string pageName = "pages/codecon.aspx";
SPSite site = new SPSite(webName);
SPWeb web = site.OpenWeb();
Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager webPartManager =
web.GetLimitedWebPartManager(
pageName,
System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
In the first step we will initialize a number of variables that we will need. These will be used in the code samples below. To compile all the code you will need a reference to the Microsoft.SharePoint.dll
Step 2 - Add the webparts.
In this step I will add a provider and a consumer webpart to the page. These webparts are the webparts that I introduced in the first post of this series.
// Create and add a new provider webpart to the page.
WebPart provider = new TST.TestCode.WebParts.FilterProvider();
provider.Title = providerName;
webPartManager.AddWebPart(provider, "Header", 1);
// Create and add a new consumer webpart to the page.
WebPart consumer = new TST.TestCode.WebParts.FilterConsumer();
consumer.Title = consumerName;
webPartManager.AddWebPart(consumer, "Header", 2);
The webparts will be added to the "Header" webpart zone that was defined in the page layout. There is no need to call a Save or Update method. After calling AddWebPart and a page refresh, the webparts will be added to the page:
Step 3 - Get the connection points.
Webpart connections are not directly created between the webparts themselves, but between connection points. Both provider and consumer can have multiple connection point. After the second article in this series, the provider webpart supported 2 types of connections ("Send Region To" and "Send Default region To"). Therefore this webpart supports 2 connections point, and we will need to find the correct point that supports the connection that we want to establish.
// Get the connection point for the consumer.
System.Web.UI.WebControls.WebParts.ConsumerConnectionPointCollection consumerConnections =
webPartManager.GetConsumerConnectionPoints(consumer);
ConsumerConnectionPoint consumerConnection = null;
foreach (ConsumerConnectionPoint cpoint in consumerConnections)
{ if (cpoint.InterfaceType == typeof(Microsoft.SharePoint.WebPartPages.IFilterValues))
{ consumerConnection = cpoint;
break;
}
}
// Get the connection point for the provider.
System.Web.UI.WebControls.WebParts.ProviderConnectionPointCollection providerConnections =
webPartManager.GetProviderConnectionPoints(provider);
ProviderConnectionPoint providerConnection = null;
foreach (ProviderConnectionPoint ppoint in providerConnections)
{ if (ppoint.InterfaceType == typeof(Microsoft.SharePoint.WebPartPages.ITransformableFilterValues))
{ providerConnection = ppoint;
break;
}
}
For the provider the connection point we are interested in, is the connection point with the InterfaceType "ITransformableFilterValues". "IFilterValues" is the connection type that our consumer supports (see the code in this article).
Step 4 - Setup the parameter.
The connection that we will use between our webparts supports a parameter. When the webparts are connected manually through the user interface, a user has to select one of the fields returned by the consumer webpart (see the SetFilter method of the consumer in part 1.). When we connect webparts through code, we have to do this ourselves. This is done by creating a special "transformer" object and setting the parametername.
// Get a new transformer object.
string parameterName = "Region";
Microsoft.SharePoint.WebPartPages.TransformableFilterValuesToFilterValuesTransformer transformer =
new Microsoft.SharePoint.WebPartPages.TransformableFilterValuesToFilterValuesTransformer();
transformer.MappedConsumerParameterName = parameterName;
The transformer object I used is an out of the box SharePoint transformer. The parametername is set to "Region", as this is one of the parameter to choose from returned by the consumer webpart.
Step 5 - Connect the webparts.
The last step is to use the 2 connection point and the transformer and connect the 2 webparts.
// Get a new connection using the 2 connection points.
Microsoft.SharePoint.WebPartPages.SPWebPartConnection newConnection =
webPartManager.SPConnectWebParts(
provider, providerConnection,
consumer, consumerConnection, transformer);
// Add the new connection
webPartManager.SPWebPartConnections.Add(newConnection);
After running the code on an empty page, the 2 webparts are added to the page, and the are connected:
Step 6 - Add and connect from the page layout
The last thing I will show in this article is how to do exactly the same thing in the page layout. When users create pages based on this layout, they will have the 2 webparts connected on their new pages automatically.
The first part adds the provider:
<WebParts:FilterProvider
runat="server"
Title="Filter Provider"
ChromeType="None"
WebPart="true"
ID="FilterProvider1"
__MarkupType="vsattributemarkup"
__WebPartId="{279CA8BF-EF33-4813-97B1-060D00BD96AF}" __designer:IsClosed="false"
partorder="1">
</WebParts:FilterProvider>
The "WebParts" prefix is a prefix that references my assembly:
<%@ Register tagprefix="WebParts"
namespace="TST.TestCode.WebParts"
assembly="TST.TestCode.WebParts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=eb8e9a85494125d0" %>
The snippet below adds the consumer webpart to the page layout:
<WebParts1:FilterConsumer
runat="server"
ID="FilterConsumer1"
Title="Filter Consumer"
__MarkupType="vsattributemarkup"
__WebPartId="{D5CAA0EB-4705-4DE6-8C14-0AF6D2C977CB}" WebPart="true"
__designer:IsClosed="false"
partorder="1">
</WebParts1:FilterConsumer>
These 2 snippets are added to one of the WebPartZones on the page. The connection between the 2 webparts is made in a different object (SPProxyWebPartManager). This is placed in one of the placeholders.
This proxy manager adds the webpart connection (SPWebPartConnection) that holds the transformerobject (TransformableFilterValuesToFilterValuesTransformer):
<WebPartPages:SPProxyWebPartManager runat="server" id="ProxyWebPartManager">
<SPWebPartConnections>
<WebPartPages:SPWebPartConnection
ID="g_0ECAEED5273C475AA0126B9F0395ADB8"
ConsumerConnectionPointID="UniqueIDForConsumer"
ConsumerID="FilterConsumer1"
ProviderConnectionPointID="UniqueIDForRegionConnection"
ProviderID="FilterProvider1">
<WebPartPages:TransformableFilterValuesToFilterValuesTransformer
MappedConsumerParameterName="Region" />
</WebPartPages:SPWebPartConnection>
</SPWebPartConnections>
</WebPartPages:SPProxyWebPartManager>
The ConsumerID and the ProviderID are equal to the IDs used when adding the webparts to the page layout. The ID for the connection points are the IDs that are set in the code of the webparts. See the first part of this series.
Hope this helps you when you are struggling with connecting webpart, either through code of in a page layout. Enjoy!