This is one thing that I have used a few times through the browser and always thought it was a feature missing from WSS 3.0 / MOSS 2007. But it was only when I tried to do this (relatively simple) thing as part of a list definition that I realised how oblique it was, and how little information there seems to be explaining how to do it… This blog post will try to address some of that.
So first off .. what is a Related List Webpart? This wasn’t really a surprise but if you look under the hood you will notice that when you use the “Related List” ribbon button then it actually does 2 things:
- Adds a new List View Webpart (in this case an XsltListViewWebPart) which is bound to the related list
- Creates a web part connection from the (already present) ListFormWebPart which provides the ID which the related list will filter on.
In order to set this up programmatically we basically have to replicate this. In my example I am running this from a Feature Receiver which will setup the web parts. I have 2 lists which I will be referring to:
- Main List (the main list which I will be modifying)
- Related List (a list which contains a lookup field containing values from List A)
STEP 1 – Add a new List View Web Part to the List Form
In this step we will be modifying the DISPLAY form (DispForm.aspx). This is probably the most common approach although you can follow very similar steps for the Edit Form if you so wish)
// these are the 2 lists we will work with
SPList mainList = web.Lists[“Main List”];
SPList relatedList = web.Lists[“Related List”];
// this is the Display Form web part page
SPFile dispForm = web.GetFile(mainList.DefaultDisplayFormUrl);
// get the web part manage which we will use to interact
SPLimitedWebPartManager wpm =
dispForm.GetLimitedWebPartManager System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
// only execute this code if there is a single web part (the default for this list)
// we don’t want to add the web parts over and over again ..
if (wpm.WebParts.Count == 1)
{
// create our List View web part
XsltListViewWebPart wp = new XsltListViewWebPart();
// Hook up the list and the view
wp.ListId = relatedList.ID;
wp.ListName = relatedList.ID.ToString();
wp.ViewGuid = relatedList.DefaultView.ID.ToString();
wp.XmlDefinition = relatedList.DefaultView.GetViewXml();
// set basic properties along with the title
wp.AllowConnect = true;
wp.Title = “Related items from “ + relatedList.Title;
wp.ChromeType = PartChromeType.TitleAndBorder;
// add the web part to the Main zone in position 2
wpm.AddWebPart(wp, “Main”, 2);
// save the page
webPartPage.Update();
}
So you can see from the example code above we are adding a simple List View webpart for our related list items. We are binding it to the “Related List” using the ID, and also choosing the View we want to display (here we have just used the Default View for simplicity).
We need to make sure we set “AllowConnect” (as we will need to use Connections in Step 2) and also set the ChromeType to “Title and Border” (as the default for Web Parts in List Forms is “None”).
Finally we add the web part and save the changes to the Web Part Page …
now for the slightly less well documented bit ..
STEP 2 – Create Web Part Connections between ListForm and ListView webparts
In this step we are going to take the Web Part which we added in STEP 1 and use standard Web Part Connections to bind them together … don’t be scared, it isn’t as hard as yoy might think 🙂
We are going to be doing several things here:
- We will get instances of both web parts which need to be connected
- We will create “Connection Point” objects for each web part
- Specify which fields we want to filter on
- We will create a “Transformer” object which is able to pass values between each web part
- We will use the Web Part Manager to create the connection, using all of that information above.
// get instances of our two web parts
System.Web.UI.WebControls.WebParts.WebPart consumer = wpm.WebParts[1];
System.Web.UI.WebControls.WebParts.WebPart provider = wpm.WebParts[0];
// Create our two Connection Point objects
// These are specific to our two types of Web Part
ProviderConnectionPoint providerPoint = wpm.GetProviderConnectionPoints(provider)[“ListFormRowProvider_WPQ_”];
ConsumerConnectionPoint consumerPoint = wpm.GetConsumerConnectionPoints(consumer)[“DFWP Filter Consumer ID”];
// create our “Transformer”
// we also specify which Field names we want to “connect” together
// here I am connecting my Related List’s “MyLookupField” and filtering it
// using the “ID” of my List Form’s item.
SPRowToParametersTransformer optimus = new SPRowToParametersTransformer();
optimus.ProviderFieldNames = new string[] { “ID” };
optimus.ConsumerFieldNames = new string[] { “MyLookupField” };
// Connect the two web parts together, using our Connection Point objects
// along with our Transformer
wpm.SPConnectWebParts(provider, providerPoint, consumer, consumerPoint, optimus);
And that is it! You don’t need to do any more “Update” or “Save” methods .. your Related List web part should now be finished 🙂
So just to be clear, we are using the standard SPLimitedWebPartManager object and calling the SPConnectWebParts method. The only slightly odd call is the reference to the “SPRowToParametersTransformer” which is specific to the type of Connection we are making (the List Form representing a “Row”).
Where did this information come from?
This is the easy bit 🙂 I added a Related Lists Webpart using the browser, then opened up DispForm.aspx using SharePoint Designer .. and found this:
<WebPartPages:SPWebPartConnection ConsumerConnectionPointID=”DFWP Filter Consumer ID” ConsumerID=”g_dc64a1e0_c2f4_4302_86df_e4d184203bbd” ID=”c225174896″ ProviderConnectionPointID=”ListFormRowProvider_WPQ_” ProviderID=”g_ffb9e36b_bc6d_489e_b7fc_e93048c32f5c”><WebPartPages:SPRowToParametersTransformer ConsumerFieldNames=”IMSDataSource” ProviderFieldNames=”ID”></WebPartPages:SPRowToParametersTransformer>
I have highlighted the references to the 3 things which made all of the dots join up for me: )
so if you are ever stuck, make sure you look in SharePoint Designer for :
- Consumer Connection Point ID (“DFWP Filter Consumer ID”)
- Provider Connection Point ID (“ListFormRowProvider_WPQ_”)
- Transformer Type (SPRowToParametersTransformer)
So thats it 🙂 Hope this was useful, comments always welcome