Programmatically Connect SharePoint Web Parts

In this post I am adding two web parts into a page programmatically and then connect them by using SPLimitedWebPartManager.SPConnectWebParts. Lately, I have been using Performance point web part and QueryStringFilter web part so I am going to use them for this example.

First step is to create an instance of the two web parts :


//Create an instance of the PerformancePoint web part 
ReportViewWebPart wp = new ReportViewWebPart();
wp.LocationUrl = "/TestBI/Lists/PerformancePoint Content/200_.000";

//Create an instance of the query string filter web part
QueryStringFilterWebPart filterwebpart = new QueryStringFilterWebPart();
filterwebpart.ZoneID = "Zone 1";
filterwebpart.DefaultValue = "Perth";
filterwebpart.QueryStringParameterName = "City";
filterwebpart.ID = "g_" + Guid.NewGuid();
filterwebpart.FilterName = "MyFilter";
filterwebpart.Title = "Hello";

Once we have created the web parts, we can add those web parts into a page by using SPLimitedWebPartManager


using (SPLimitedWebPartManager wpm = web.GetLimitedWebPartManager("/TestBI/Dashboards/MyTest/TestPage.aspx",System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))                                                                     
            {
                wpm.AddWebPart(filterwebpart, "Zone 1", 0);
                wpm.AddWebPart(wp, "Zone 1", 1);                

                var cc = wpm.GetConsumerConnectionPoints(wp);
                var pp = wpm.GetProviderConnectionPoints(filterwebpart);

                var transformer = = new TransformableFilterValuesToParametersTransformer();

            filter.ConsumerFieldNames = new string[] {"SqlReportViewUniqueParameterIdSI1"};
            filter.ProviderFieldNames = new string[] { "MyFilter" };

ConsumerConnectionPoint consumerConnection = null;

                foreach (ConsumerConnectionPoint cpoint in cc)
                {
                    if (cpoint.InterfaceType == typeof(IWebPartParameters))
                        consumerConnection = cpoint;
                }

                ProviderConnectionPoint providerConnection = null;

                foreach (ProviderConnectionPoint ppoint in pp)
                {
                    if (ppoint.InterfaceType == typeof(ITransformableFilterValues))
                        providerConnection = ppoint;

                }

                var conn = wpm.SPConnectWebParts(filterwebpart, providerConnection , wp, consumerConnection, transformer);

                wpm.SPWebPartConnections.Add(conn);
            }

The QueryStringFilterWebPart resides in Microsoft.Office.Server.FilterControls.dll which resides in GAC.

As for the ReportViewWebPart, it resides in Microsoft.PerformancePoint.Scorecards.WebControls.dll which can found in GAC.

SharePoint: Custom provider web part

Got a requirement to read a querystring and pass it to some of the web parts on a page. I thought that this would be easy since I can use the OOTB query string url filter web part to read and then pass the value after setting up the connection.

However, apparently some of the consumer web parts need the value to be in different format. My first thought was to append another querystring with the same value (just different format) but that would not be very nice (especially when the url length is restricted). This is where ITransformableFilterValues comes in handy. The interface is used for web part to web part connections.

Below are an example on how this interface can be implemented.


public class CustomQueryStringFilterWebPart : System.Web.UI.WebControls.WebParts.WebPart, ITransformableFilterValues
    {        
        string _queryStringKey = "category";
		string _filterValue = "";
		
        [WebPartStorage(Storage.Shared)]
        [WebBrowsable(true)]
        [WebDisplayName("Query String Key")]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Settings")]
        public string QueryStringKey
        {
            get { return _queryStringKey; }
            set { _queryStringKey = value; }
        }      

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            _filterValue = HttpContext.Current.Request.QueryString[_queryStringKey];
        }

        public bool AllowAllValue
        {
            get { return true; }
        }

        public bool AllowEmptyValue
        {
            get { return false; }
        }

        public bool AllowMultipleValues
        {
            get { return false; }
        }

        public string ParameterName
        {
            get { return "Query String Filter"; }
        }

        public System.Collections.ObjectModel.ReadOnlyCollection<string> ParameterValues
        {
            get
            {
                string value = string.Format("[{0}]", _filterValue.ToUpper());
                string[] values = new string[] { value };
                return new ReadOnlyCollection<string>(values);
            }
        }

        [ConnectionProvider("Query String Filter", "ITransformableFilterValues", AllowsMultipleConnections = true)]
        public ITransformableFilterValues SetConnectionInterface()
        {
            return this;
        }        
    }

The code above is a custom web part that implements ITransformableFilterValues. It gets the querystring value and convert it to uppercase.

Add the above web part to a page and to pass the transformed value, connections to the consumer web parts need to be created. Once the connection is setup, everything should just work 🙂

Create a new Wiki Page

The code below adds a new wiki page and then inserts a web part into the new page’s rich text editor

SPList pagesList = web.Lists["Pages"];

SPFolder rootFolder = pagesList.RootFolder;

SPFileCollection fileCollection = rootFolder.Files;

string pageUrl = rootFolder.ServerRelativeUrl + "/MyNewPage.aspx";

//Create the page
SPFile newFile = fileCollection.Add(pageUrl, SPTemplateFileType.WikiPage);

//Checkout and add custom web part to the newly created page
newFile.CheckOut();

//Use a new Guid as the web part id
Guid storageKey = Guid.NewGuid();

string wpId = String.Format("g_{0}", storageKey.ToString().Replace('-', '_'));

//Get web part manager
using (SPLimitedWebPartManager manager = newFile.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))

{

//Initialize the web part and insert it into 'wpz' web part zone.
//Web part zone is hidden in Rich text editor and its name is fixed ('wpz')

MyWebPart webPart = new MyWebPart();

webPart.ID = wpId;

webPart.Title = "My New Page";

manager.AddWebPart(webPart, "wpz", 0);

string content = String.Format(CultureInfo.InvariantCulture
, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"></div></div>"

, new object[] { storageKey.ToString("D") });

SPListItem item = newFile.Item;

item["WikiField"] = content;

item.Update();

}
newFile.CheckIn(string.Empty);

Hope that helps 🙂

A quick and easy way to read RSS in SharePoint Foundation 2010

Thanks to George Tsiokos for his Data view web part http://sharepointrss.com/, we just have to submit the form on the site. This will produce a .DWP file. Save the .DWP file to your local drive and the next step is to upload this .DWP file to a web part page in SharePoint and you can view the RSS feed. No installation required 🙂

Add Content Editor Web Part into Site Template

In Onet.xml, find the module(s) that need to have a content editor web part and add the following:


<AllUsersWebPart WebPartZoneID="Left" WebPartOrder="1">
          <![CDATA[
          <WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
            <Title>My Web part</Title>
            <FrameType>None</FrameType>
            <Description>Say Hello Web Part</Description>
            <FrameState>Normal</FrameState>
            <Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
            <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
            <ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
            <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">
                &lt;script&gt; 

                function SayHello() 
                { 
			alert('Hello');
                  	
                      //all done 
                      return; 
                    } 
                  } 
                }


                _spBodyOnLoadFunctionNames.push(&quot;SayHello&quot;) 

                &lt;/script&gt;
            </Content>
            <PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
          </WebPart>
          ]]>

        </AllUsersWebPart>

Note some characters need to be encoded.

In case a web part is broken, use contents=1 query string, for example: http://myurladdress/default.aspx?contents=1. This will show a list of all the web parts on the page.

Cheers 🙂