Click here to Skip to main content
Click here to Skip to main content

Connecting Custom Web Parts in SharePoint

By , 10 Jun 2009
 

article.gif

Introduction

SharePoint is a rich and powerful platform for both users and developers. We can customize and enrich SharePoint in many ways. One of the common ways is creating custom Web Parts. With a custom Web Part, we can implement our features quick and clean. One of the useful features of MOSS Web Parts is the ability to send and receive parameters. We can easily filter a data view Web Part according to the results of another Web Part. It's good to know that we can connect our custom Web Parts as well.

Requirements

The Web Part created in this article will use Windows SharePoint Services 3.0. It will also work with MOSS 2007. To create the Web Part, we will be using Visual Studio 2005 installed on Windows Server 2003 with Extension for Windows SharePoint Services version 1.1 (you can also use Visual Studio 2008 with the Extension of WSS version 1.2). WSS or MOSS is also installed. You can use Microsoft Virtual PC for setting up such an environment in your development machine.

Creating ProviderWebPart in Visual Studio

  1. Create a Web Part project in Visual Studio and name it ProviderWebPart.
  2. addnewwebpart.gif

  3. Delete the WebPart1 folder in Solution Explorer.
  4. Right click on the project and choose Add New Item and then choose Web Part. Change the name of the Web Part to ProviderWebPart.
  5. Use the following code inside the Web Part class:
  6. public class ProviderWebPart : System.Web.UI.WebControls.WebParts.WebPart
    {
        TextBox txt;
        Button btn;
    
        public ProviderWebPart()
        {
            this.Title = "Provider WebPart";
            this.ExportMode = WebPartExportMode.All;
        }
    
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
    
            Table tbl;
            TableRow row;
            TableCell cell;
    
            // A table for layout 
            tbl = new Table();
            row = new TableRow();
            cell = new TableCell();
            
            // first row for title
            cell.ColumnSpan = 2;
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            Label lblTitle = new Label();
            lblTitle.Text = "This WebPart will send a parameter to a consumer:";
            cell.Controls.Add(lblTitle);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
    
            // second row of table for textbox and button
            row = new TableRow();
            cell = new TableCell();
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            txt = new TextBox();
            txt.Text = "";
            txt.Width = Unit.Pixel(120); ;
            cell.Controls.Add(txt);
            row.Controls.Add(cell);
            cell = new TableCell();
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            btn = new Button();
            btn.Text = "Send...";
            btn.Click += new EventHandler(btn_Click);
            cell.Controls.Add(btn);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
            
            //add table to webpart
            this.Controls.Add(tbl);
        }
    
        void btn_Click(object sender, EventArgs e)
        {
            // will be added later
        }
    }

    Note: The above code will render the interface of the ProviderWebPart.

  7. Now, we declare an interface for communication between two Web Parts. We must create a class library project with a strong name. To do so, go to the File menu and choose Add New Project and then select Class Library. Name it CommunicationInterface.
  8. Rename class1.cs to ICommunicationInterface.cs and replace the following code in that file:
  9. namespace CommunicationInterface
    {
        public interface ICommunicationInterface
        {
            string Parameter1 { get; }
        }
    }

    As you can see, we declared an interface for communication with one parameter. You can extend it and add your own parameters.

  10. Right click on CommunicationInterface and choose properties; in the Signing tab, check "Sign the Assembly", and then in the dropdown list, select <New...> and name the file key1.snk and uncheck Protect key file with password.
  11. strong.gif

  12. Right click and Build the CommunicationInterface project.
  13. In the ProviderWebPart project, right click and Add reference, and then choose the Projects tab and the CommunicationInterface project.
  14. Double-click on ProviderWebPart.cs. Now, we must implement the interface in our Web Part class, so add this code to the class:
  15. Use CommunicationInterface;

    and change the class declaration to:

    public class ProviderWebPart : 
           System.Web.UI.WebControls.WebParts.WebPart, 
           ICommunicationInterface
  16. Implement the Parameter1 property in the Web Part class using the following code:
  17. // implement the Parameter1 property from interface
    protected string _parameter1 = "";
    public string Parameter1
    {
        get { return _parameter1; }
    }
  18. Create the property that returns the interface and decorate it with the ConnectionProvider attribute. The parameters of ConnectionProvider are the display name and the real name (ID) of the connection. When we declare more than one connection provider and consumer (like SharePoint Web Parts), we must choose a unique name for IDs of connections in a Web Part.
  19. // create a property that return the interface reference
    // and decorate it with ConnectionProvider
    [ConnectionProvider("Parameter1 Provider", 
                        "Parameter1 Provider")]
    public ICommunicationInterface ConnectionInterface()
    {
        return this;
    }
  20. Add the following code to the btn_click event:
  21. // set connection provider property with required textbox info.
    this.localParameter1 = txt.Text;

    Now, the whole code of ProviderWebPart must be like this:

    public class ProviderWebPart : 
           System.Web.UI.WebControls.WebParts.WebPart, 
           ICommunicationInterface
    {
        TextBox txt;
        Button btn;
    
        // implement the Parameter1 property from interface
        protected string _parameter1 = "";
        public string Parameter1
        {
            get { return _parameter1; }
        }
    
        // create a property that return the interface reference
        // and decorate it with ConnectionProvider
        [ConnectionProvider("Parameter1 Provider", 
                            "Parameter1 Provider")]
        public ICommunicationInterface ConnectionInterface()
        {
            return this;
        }
    
        public ProviderWebPart()
        {
            this.Title = "Provider WebPart";
            this.ExportMode = WebPartExportMode.All;
        }
    
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
    
            Table tbl;
            TableRow row;
            TableCell cell;
    
            // A table for layout 
            tbl = new Table();
            row = new TableRow();
            cell = new TableCell();
            
            // first row for title
            cell.ColumnSpan = 2;
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            Label lblTitle = new Label();
            lblTitle.Text = "This WebPart will send a parameter to a consumer:";
            cell.Controls.Add(lblTitle);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
    
            // second row of table for textbox and button
            row = new TableRow();
            cell = new TableCell();
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            txt = new TextBox();
            txt.Text = "";
            txt.Width = Unit.Pixel(120); ;
            cell.Controls.Add(txt);
            row.Controls.Add(cell);
            cell = new TableCell();
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            btn = new Button();
            btn.Text = "Send...";
            btn.Click += new EventHandler(btn_Click);
            cell.Controls.Add(btn);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
            
            //add table to webpart
            this.Controls.Add(tbl);
            
        }
    
        void btn_Click(object sender, EventArgs e)
        {
        // set connection provider property with required textbox info.
            this._parameter1 = txt.Text;
        }
    }
  22. In the properties folder, double click on AssemblyInfo.cs and change:
  23. [assembly: CLSCompliant(true)] 

    to:

    [assembly: CLSCompliant(false)]

    clscompliant.gif

  24. For successful Web Part deployment, we need to add the CommunicationInterface DLL into the GAC. So, open Windows Explorer and browse: c:\windows\assembly. Then, open another explorer instance and browse: [your solution path]\ProviderWebPart\CommunicationInterface\bin\Debug. Now, drag and drop CommunicationInterface.dll in c:\windows\assembly.
  25. Right click on the Web Part project and choose build and deploy.
  26. Now, ProviderWebPart is ready to use in SharePoint and we must create a consumer Web Part.

Creating ConsumerWebPart in Visual Studio

  1. In the File menu, add a new Web Part project to the solution and name it ConsumerWebPart.
  2. Delete the WebPart1 folder in Solution Explorer.
  3. Right click on the project and choose Add New Item, and then choose Web Part. Change the name of the Web Part to ConsumerWebPart.
  4. In the ConsumerWebPart project, right click and Add reference to the CommunicationInterface project.
  5. In the Properties folder, double click on AssemblyInfo.cs and change:
  6. [assembly: CLSCompliant(true)]

    to:

    [assembly: CLSCompliant(false)]
  7. Double click on ConsumerWebPart.cs and add following code above the class:
  8. using CommunicationInterface;
  9. In the ConsumerWebPart class, add the following code:
  10. public class ConsumerWebPart : 
           System.Web.UI.WebControls.WebParts.WebPart
    {
        Label lblTitle;
        Label lblResult;
    
        ///// the string info consumer from custom reciever   //
        ICommunicationInterface connectionInterface = null;
        // The consumer webpart  must define a method that
        // would accept the interface as an parameter
        // and must be decorated with ConnectionConsumer attribute      
        [ConnectionConsumer("Parameter1 Consumer", 
                            "Parameter1 Consumer")]
        public void GetConnectionInterface(ICommunicationInterface 
                                           _connectionInterface)
        {
            connectionInterface = _connectionInterface;
        }
        /////////////////////////////////////////////////////////  
    
        public ConsumerWebPart()
        {
            this.Title = "Consumer WebPart";
            this.ExportMode = WebPartExportMode.All;
        }
    
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
    
            Table tbl;
            TableRow row;
            TableCell cell;
    
            // A table for layout 
            tbl = new Table();
            row = new TableRow();
            cell = new TableCell();
    
            // first row for title
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            lblTitle = new Label();
            lblTitle.Text = "This WebPart will recieve " + 
                            "a parameter from a provider:";
            cell.Controls.Add(lblTitle);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
    
            //second row for result
            row = new TableRow();
            cell = new TableCell();
            cell.VerticalAlign = VerticalAlign.Middle;
            cell.HorizontalAlign = HorizontalAlign.Center;
            lblResult = new Label();
            //check the connectionInterface for recieving the parameter1
            if (connectionInterface != null)
            {
                lblResult.Text = connectionInterface.Parameter1+ 
                                 " is recieved!";
            }
            else
            {
                lblResult.Text = "nothing is recieved!";
            }
            cell.Controls.Add(lblResult);
            row.Controls.Add(cell);
            tbl.Controls.Add(row);
    
            //add table to webpart
            this.Controls.Add(tbl);
        }
    }
  11. Build and deploy the ConsumerWebPart project.
  12. solution.gif

Using the Created Web Parts in SharePoint and Connecting Them

After creating and deploying our Web Parts, we can check the functionality in the SharePoint environment.

  1. Broswe your SharePoint site and edit a Web Part page like default.aspx. Use Site Actions and Edit Page.
  2. Click Add Web Part in a Web Part zone; your deployed Web Parts must be in Miscellaneous. Check both ProviderWebPart and ConsumerWebPart, and click Add.
  3. addwebpart.gif

  4. Now, you can connect your Web Parts. Click on Edit in ConsumerWebPart, and in Connections; check Get Paramet1 consumer from ProviderWebPart.
  5. Now, click on Exit edit mode on the top of the page.
  6. Check the functionality of our Web Parts. Type a word and click the "Send..." button and check the ConsumerWebPart.
  7. result.gif

Additional Improvements

The presented sample was simple. You can define your parameters in CommunicationInterface and transfer them between Web Parts. Each Web Part can be a consumer and provider at the same time.

Conclusion

The sample code showed that we can connect our custom Web Parts just like Microsoft SharePoint Server Web Parts. So, we can develop more advanced and generic connected Web Parts.

History

  • 10/06/2009 - Version 1.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nioosha Kashani
Software Developer (Senior) AIRIC
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
Member
MCP (Microsoft Certified Professional)
Senior Software Developer in AIRIC (Automotive Design and Research Company).
Capabilities and interests:
.NET Framework, ASP.NET, Windows Application, Windows Workflow Foundation, SharePoint Customization and Development,SQL Server, NHibernate, BPMN and UML.
Master of Industrial Engieering from Poly-Technic of Tehran

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 4memberAbhay Malviya28 May '12 - 20:55 
This Article is good.
 
But Please update it on VS2010 and above
QuestionMy Vote Of 5memberMember 840314327 Feb '12 - 23:13 
nice Article
QuestionProgramatically connect custom webpartsmemberimran39830 Jan '12 - 0:09 
Dear sir,i have two user controls which are added whenever a subsite is created using splimitedwebpart manager class,i want to connect these two user controls.i have follow the steps which are defined by you in above article.if you have some solution.Please help me.
 
Regards Imran
GeneralMy vote of 1membervaibhav201028 Sep '11 - 0:57 
So poor thats solution not working in vs 2010
GeneralMy vote of 4memberR@je$h16 Jun '11 - 20:11 
Easy to understand...Good job
GeneralMy vote of 5memberMember 437824926 May '11 - 1:39 
good
QuestionConnecting Custom Web Part and ContentEditor Webpart [modified]memberJyothi Swaroop V10 Feb '11 - 18:45 
Is it possible to connect custom webpart and a ContentEditor Webpart and send some text to other webpart , as like connecting two custom webparts. If so please provide me some idea on that.
Thanks in Advance
 
Swaroop Vuppala
modified on Friday, February 11, 2011 1:31 AM

QuestionConnect List View Web Part to Custom Web Part [modified]memberpaschka763 Nov '10 - 21:57 
Good Article!
But do you know what should be done to connect a List View Web Part to my custom Web Part?
An LV Web Part has connection option "Send Row of Data to". Do you know what should be done (is there an interface to implement) in order for my custom web part to "receive" this row of data?
Thank You!
 

Edit: found the answer - http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.iwebpartfield.aspx
modified on Thursday, November 4, 2010 9:47 AM

GeneralAwesome and SimplememberHungry Mind10 Feb '10 - 22:29 
Hi Nioosha, I will like to say a thousand thanks to you, you have made the connectable web part learning perfect and very simple to refer, it really helped me.
 
Thank you
You should believe what u r doing and be confident that u will get success.
 
Syed Abbas Naqvi.

Generalcant deploymembersheand4 Jan '10 - 3:59 
copied the example exactly but cant deploy solution...
get the following error message:
System.Reflection.ReflectionTypeLoadException
Error: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
 
what can i do?
Generali don't have the Edit Option....membersleepwalker7895 Dec '09 - 23:06 
Hi.
i don't have edit option to set the connection :/
3. Now, you can connect your Web Parts. Click on Edit in ConsumerWebPart, and in Connections; check Get Paramet1 consumer from ProviderWebPart.
 
thx for help
GeneralRe: i don't have the Edit Option....membernicetohaveyou7 Mar '11 - 6:03 
please check your browser...open the link in IE not in firefox as the edit option does not appear in firefox.
GeneralRe: i don't have the Edit Option....membermsardar1 Apr '11 - 12:24 
Worked perfect after I changed browser to IE. Thanks a lot. Do you have any web for connecting webpartzones in the same manner or am I just dreaming! Thanks
Questionconnecting web partsmemberMember 47323851 Dec '09 - 0:32 
I tried ur example of connecting custom web part n was impressed coz it did work, now im wondering if i can do the same but using a chart, e.g i have a form and i want to connect it with a pie chart, how do i do dat?
GeneralNot working with a consumer that has TextBox instead of Labelmemberjpragnell30 Sep '09 - 22:54 
If I change the code in the consumer webpart to:

//second row for result
row = new TableRow();
cell = new TableCell();
cell.VerticalAlign = VerticalAlign.Middle;
cell.HorizontalAlign = HorizontalAlign.Center;
txtResult = new TextBox();
//check the connectionInterface for recieving the parameter1
if (connectionInterface != null)
{
txtResult.Text = connectionInterface.Parameter1+
" is recieved!";
}
else
{
txtResult.Text = "nothing is recieved!";
}

 
it simply does not work, is there some setting I need to apply to allow the consumer to have form controls?
QuestionHow does this get deployed?memberJJComcast26 Aug '09 - 6:39 
I created this successfully in my VM.
 
Can someone please supply detailed instructions about how to deploy it to my production server? It's MOSS 2007.
QuestionMultiple ParametersmemberJJComcast24 Jul '09 - 7:53 
Hello,
 
Can you please further describe how to pass multiple parameters/values to the consumer?
 
Thank you,
 
JJ
GeneralTwo Webpart load usercontrol dynamically connect together.memberLeThinh20 Jul '09 - 1:05 
Hi Nioosha Kashani, I want to provider webpart load usercontrol dynamic, and then tranfer a parameter to the second webpart, and then second webpart load usercontrol of it with parameter received. How can i do that? thank you in advance.
GeneralVSeWSS Service Errormembersudha2u30 Jun '09 - 0:24 
Hi,
 

I downloaded this project and try to package the webpart during that time getting the following error
 
Error 1 VSeWSS Service Error: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
 
Log file written to: C:\Documents and Settings\Default User\Application Data\Microsoft\VSeWSS 1.3\VSeWSS1.3 service.log
 

System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)
at System.Reflection.Module.GetTypes()
at Microsoft.SharePoint.Tools.Reflection.ModuleWrapper.GetTypes()
at Microsoft.SharePoint.Tools.Reflection.TypeFinder.GetTypesAsType(IAssemblyWrapper assembly, ITypeWrapper targetType)
at Microsoft.SharePoint.Tools.Reflection.TypeFinder.Find(IAssemblyWrapper assembly, ITypeWrapper targetType)
at Microsoft.SharePoint.Tools.SharePointProxies.WSPViewFacade.FindClasses(IAssemblyWrapper assembly)
at Microsoft.SharePoint.Tools.SharePointProxies.WSPViewFacade.GetAssemblyFeatureElementDirectorClassMap(String projectAssemblyPath)
at VSeWSS.Server.Services.SPService.GetAssemblyFeatureElementDirectorClassMap(String projectAssemblyPath)
 
I am new to webpart development.
Can you please help me.
 
Regards,
Sudhakar
GeneralRe: VSeWSS Service ErrormemberMember 8221417 Aug '09 - 6:04 
Did you ever find a solution to this issue? i'm currently hitting it with VSeWSS 1.3
GeneralRe: VSeWSS Service Errormembersivaraj rp31 Aug '09 - 8:34 
I faced same error. I solved it by adding the interface dll to GAC.
GeneralRe: VSeWSS Service Errormemberahmz201012 Jun '10 - 21:21 
i also faced the same error. just gac the dll and restarted the vs. its working fine now.
Generalconnection interface is always null in the Consumer WebPart.memberabin jaik22 Jun '09 - 23:12 
I have downloaded the sample code project(.zip file) from this article and deployed the same into my Sharepoint Site. I have added the both webparts on my page.But functionality is not working ,when i tried with entering a value in the provider webpart and pressed the "Send.." button. It always shows a message like "This WebPart will recieve a parameter from a provider: nothing is recieved! ".
When i debugged i found that connection interface is always null in the Consumer WebPart.Please help me to fix this issue. Thanks
 
if (connectionInterface != null)
{
lblResult.Text = connectionInterface.Parameter1+" is recieved!";
}
else
{
lblResult.Text = "nothing is recieved!";
}
 
ABIN JAIK ANTONY

GeneralRe: connection interface is always null in the Consumer WebPart.memberNioosha Kashani26 Jun '09 - 19:18 
Did you notice the step 3 of "Using Created Web Parts in SharePoint and Connecting Them" section of this article?
You must tell the MOSS that these two web part are connected.
Pls check this and let me know.
AnswerRe: connection interface is always null in the Consumer WebPart.memberJJComcast21 Jul '09 - 7:19 
My interface was always Null also.
 
I fixed it by setting the Connection in the Provider web part as well telling it that it will send a parameter to the consumer web part. I deleted and re-added the provider web part first.
 
I think that is missing from the instructions.
GeneralRe: connection interface is always null in the Consumer WebPart.memberdootndo217 Nov '09 - 12:19 
The solution is to read the property in OnPreRender not during CreateChildControls method.
 
In the Consumer, move this code block from CreateChildControls method:
 
//check the connectionInterface for recieving the parameter1
if (connectionInterface != null)
{
    lblResult.Text = connectionInterface.Parameter1 is recieved!";
}
else
{
    lblResult.Text = "nothing is recieved!";
}
 
to:
 
protected override void OnPreRender(EventArgs e)
{
	base.OnPreRender(e);
 
	if (connectionInterface != null)
        {
            lblResult.Text = connectionInterface.Parameter1+ 
                             " is recieved!";
        }
        else
        {
            lblResult.Text = "nothing is recieved!";
        }
}
 
OnPreRender is called after the ConnectionConsumer code is called. It will always be null in CreateChildControls().
 
dootndo2
GeneralOnPreRendermemberstasDav16 Jun '09 - 3:38 
This helped me creating the base for my connectable Web Parts.
I only had to change a small piece of code. To get the value in the Consumer WebPart, I had to place the following code in 'OnPreRender'.
 
   //check the connectionInterface for recieving the parameter1
   if (connectionInterface != null)
   {
      lblResult.Text = connectionInterface.Parameter1+" is recieved!";
   }
   else
   {
      lblResult.Text = "nothing is recieved!";
   }

GeneralRe: OnPreRendermemberMember 417804526 Jun '09 - 4:11 
I Still get connection interface as null even in Onprerender.
GeneralRe: OnPreRendermemberMember 417804526 Jun '09 - 4:41 
Got this working...one step in MOSS which is not mentioned here is to configure the web part in Edit Mode to receive Paramter1 from Provider Webpart through UI.
 
After this it is working for me.
Please let me know if this step is not required.
 
Thanks
GeneralRe: OnPreRendermemberNioosha Kashani26 Jun '09 - 19:11 
This step is required because we provide infrastructure for connecting web parts but the final user must use this feature through UI.
GeneralRe: OnPreRendermemberMember 417804528 Jun '09 - 19:19 
I agree..Thanks Nioosha
GeneralRe: OnPreRendermemberdootndo217 Nov '09 - 12:20 
Sorry, I posted the same solution far after you already did. DUH! Sorry. D'Oh! | :doh:
GeneralRe: OnPreRendermemberanilch12320 Mar '10 - 5:29 
Yes.. This step is required for Moss. Thanks alot

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 10 Jun 2009
Article Copyright 2009 by Nioosha Kashani
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid