Freigeben über


Step by Step - Creating Connected SharePoint Web Parts using IWebPartField interface and using Editor Part and User Controls

I was eagerly waiting for the release of VSeWSS version 1.2 for VS 2008. Without it developing custom SharePoint applications in VS 2008 was like nightmare. Let us explore it by creating connected web parts. This time we will create connected Web Parts similar to the one we have created earlier.

Things we will do here:

  1. We will use standard IWebPartField interface.
  2. We will use Categories and Products table from Northwind database as the data sources. We will use a dropdown in the provider web part to show all categories and we will use a GridView in the Consumer Web Part to show the Products data.
  3. We will use Editor Part for changing the properties (font color in the GridView) of the Consumer Web Part.
  4. We will use Web User Controls for both the Web Parts and also the Editor Part.

Step 1:

Start VS 2008 and select new Project and select Visual C#>SharePoint>Web Part. Change the name as ContosoStandardConWP. In the Solution explorer select the folder Webpart1 and delete it. Add reference of System.Drawing to the Project.

Right click on the project and select Add>New Item. Select SharePoint>Web Part and change the name ContosoStandardConProviderWP and similarly add another Web Part and name it as ContosoStandardConConsumerWP.

Again right click on the project and select Add>New Item. Select Code>Class. Change the name as ContosoStandardConEP.cs.

Right click on the project and select Add>New Folder. Name it as Templates. Similarly create another folder under Templates and name it controltemplates. Right click on controltemplates and select Add>New Item. In the new item window select General and Text File. Change the name of the Text File as ContosoStandardConProviderUC.ascx. Similarly add 2 more files and change the name as ContosoStandardConConsumerUC.ascx and ContosoStandardConEPUC.ascx.

Step 2:

Now open the ContosoStandardConProviderUC.ascx file and from the Toolbox add a DropDownList into it. Similarly add one GridView into ContosoStandardConConsumerUC.ascx and another DropDownList into ContosoStandardConEPUC.ascx. Keep the name of these controls as default. You may find that the design mode is not working for these User Controls. If required you can create a separate application (web site) and can add web user control there and can add and see all these controls in design mode and can copy the HTML from there to our project.

Step 3:

Open ContosoConProviderWP.cs file and add these using statements:

using System.Data;

using System.Data.SqlClient;

using System.ComponentModel;

Change the class statement from:

public class ContosoStandardConProviderWP : System.Web.UI.WebControls.WebParts.WebPart

to

public class ContosoStandardConProviderWP : System.Web.UI.WebControls.WebParts.WebPart, IWebPartField

Before the default constructor add the following lines:

DropDownList CatList;

        UserControl userControl;

        int CatListVal = 0;

        public int CategoryID

        {

            get

            {

                return this.CatListVal;

            }

        }

        [ConnectionProvider("Web part Connection Provider")]

        public IWebPartField GetWPConnectFieldProvider()

        {

            return this;

        }

        public void GetFieldValue(FieldCallback callback)

        {

            callback.Invoke(this.CatListVal);

        }

        public PropertyDescriptor Schema

        {

            get

            {

                return TypeDescriptor.GetProperties(this)["Web part Connection Provider"];

            }

        }

Step 4:

Replace the content of the CreateChildControls method with the following:

            userControl = (UserControl)Page.LoadControl(@"/_controltemplates/ContosoStandardConProviderUC.ascx");

            CatList = (DropDownList)userControl.FindControl("DropDownList1");

            SqlConnection newSqlConnection = new SqlConnection();

            SqlCommand newSqlCommand = new SqlCommand("Select CategoryID,CategoryName from categories", newSqlConnection);

            newSqlCommand.CommandType = System.Data.CommandType.Text;

            newSqlConnection.ConnectionString = "Integrated Security=True;Initial Catalog=Northwind;Data Source=pranab-sec";

            newSqlConnection.Open();

            CatList.DataValueField = "CategoryID";

            CatList.DataTextField = "CategoryName";

            CatList.AutoPostBack = true;

            CatList.DataSource = newSqlCommand.ExecuteReader();

            CatList.DataBind();

            CatList.SelectedIndexChanged += new EventHandler(CatList_SelectedIndexChanged);

            Controls.Add(userControl);

            newSqlConnection.Close();

After CreateChildControls method add these lines:

        void CatList_SelectedIndexChanged(object sender, EventArgs e)

        {

            this.CatListVal = int.Parse(this.CatList.SelectedValue);

        }

        protected override void Render(HtmlTextWriter writer)

        {

            EnsureChildControls();

            this.userControl.RenderControl(writer);

        }

       

Step 5:

Open ContosoConConsumerWP.cs file and add these using statements:

using System.Data;

using System.Data.SqlClient;

using System.Collections.Generic;

using System.Drawing;

Change the class statement from:

public class ContosoStandardConConsumerWP : System.Web.UI.WebControls.WebParts.WebPart

to

public class ContosoStandardConConsumerWP : System.Web.UI.WebControls.WebParts.WebPart,IWebEditable

Before the default constructor add the following lines:

protected int selectedCatID;

        protected GridView NewDataGrid;

        protected UserControl userControl;

        protected string SqlQuery = "Select ProductID,ProductName,UnitPrice from Products";

        [WebBrowsable(false), Personalizable(true)]

        public string DisplayFontName

        {

            get;

            set;

        }

        [ConnectionConsumer("Web Part Consumer")]

        public void GetWPConnectedProviderInterface(IWebPartField connectProvider)

        {

            FieldCallback callback = new FieldCallback(ReceiveField);

            connectProvider.GetFieldValue(callback);

        }

        public void ReceiveField(object objField)

        {

            if (objField != null)

            {

                this.selectedCatID = (int)objField;

                if (this.selectedCatID != 0)

                    this.SqlQuery += " where CategoryID = " + this.selectedCatID.ToString();

            }

        }

        protected override void OnPreRender(EventArgs e)

        {

            SqlConnection newSqlConnection = new SqlConnection();

            SqlCommand newSqlCommand = new SqlCommand(this.SqlQuery, newSqlConnection);

            newSqlCommand.CommandType = System.Data.CommandType.Text;

            newSqlConnection.ConnectionString = "Integrated Security=True;Initial Catalog=Northwind;Data Source=pranab-sec";

            newSqlConnection.Open();

            NewDataGrid.DataSource = newSqlCommand.ExecuteReader();

            NewDataGrid.DataBind();

            newSqlConnection.Close();

            newSqlConnection.Dispose();

            newSqlCommand.Dispose();

            this.Controls.Add(userControl);

        }

Step 6:

Replace the content of CreateChildControls method with the following:

            userControl = (UserControl)Page.LoadControl(@"/_controltemplates/ContosoStandardConConsumerUC.ascx");

            NewDataGrid = (GridView)userControl.FindControl("GridView1");

            Style myStyle = new Style();

            myStyle.ForeColor = Color.Black;

            if (DisplayFontName != null)

            {

                switch (DisplayFontName.ToString())

                {

                    case "Red":

                        myStyle.ForeColor = Color.Red;

                        break;

                    case "Blue":

                        myStyle.ForeColor = Color.Blue;

                        break;

                    case "Green":

                        myStyle.ForeColor = Color.Green;

                        break;

  default:

                        myStyle.ForeColor = Color.Black;

                        break;

                }

            }

            NewDataGrid.ApplyStyle(myStyle);

After CreateChildControls method add these lines:

protected override void Render(HtmlTextWriter writer)

        {

            EnsureChildControls();

            this.userControl.RenderControl(writer);

        }

        EditorPartCollection IWebEditable.CreateEditorParts()

        {

            List<EditorPart> editors = new List<EditorPart>();

            editors.Add(new ContosoStandardConEP(this.ID));

            return new EditorPartCollection(editors);

        }

        object IWebEditable.WebBrowsableObject

        {

            get { return this; }

        }

Step 7:

Open up ContosoStandardConEP.cs file and change the entire content as:

using System;

using System.Collections.Generic;

using System.Text;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.WebControls;

using System.Web.UI;

namespace ContosoStandardConWP

{

    class ContosoStandardConEP : EditorPart

    {

        DropDownList ddlDisplayFont;

        UserControl userControlToolPart;

        public ContosoStandardConEP(string webPartID)

        {

            this.ID = "ContosoStandardConConsumerWP" + webPartID;

            this.Title = "Select Font Color";

            this.Description = "Select Font Color for Products";

        }

        protected override void CreateChildControls()

        {

            userControlToolPart = (UserControl)Page.LoadControl(@"/_controltemplates/ContosoStandardConEPUC.ascx");

            ddlDisplayFont = (DropDownList)userControlToolPart.FindControl("DropDownList1");

           

            //You can make the item adding part dynamic

            ddlDisplayFont.Items.Add("Red");

            ddlDisplayFont.Items.Add("Blue");

            ddlDisplayFont.Items.Add("Green");

            ddlDisplayFont.Items.Add("None");

            //////////////////////////////////////

           

            Controls.Add(userControlToolPart);

        }

        public override bool ApplyChanges()

        {

            EnsureChildControls();

            ContosoStandardConConsumerWP webPart = WebPartToEdit as ContosoStandardConConsumerWP;

            if (webPart != null)

            {

                webPart.DisplayFontName = ddlDisplayFont.SelectedValue;

            }

            return true;

        }

        public override void SyncChanges()

        {

            EnsureChildControls();

            ContosoStandardConConsumerWP webPart = WebPartToEdit as ContosoStandardConConsumerWP;

            if (webPart != null)

                ddlDisplayFont.SelectedValue = webPart.DisplayFontName;

        }

    }

}

Step 8:

Right click on the project once again and go to properties and in the Debug tab and Start Browser with URL add the destination site’s URL. Now deploy the application from Build>Deploy menu and open the URL in a browser.

Step 9:

In the site click on Site Actions>Edit Page and click on Add a Web Part in any Web Part Zone. This will open up the Web Part gallery and under Misceleneous section you will find ContosoStandardConProviderWP and ContosoStandardConConsumerWP Web Parts. Select the Web Parts and those will be added to the Web Part Zone. Click on the Edit option at ContosoStandardConConsumerWP and select Connections>Get Web Part Consumer From> ContosoStandardConProviderWP. Now if you exit the edit mode you can see 2 Web Parts. If you select a value from the categories, corresponding products will be shown. Again if you modify the consumer Web Part you can find an option in the Web Part task pane to change the font color of the Web Part. Select a new value and you can see it changes the color.

Comments

  • Anonymous
    July 02, 2008
    PingBack from http://blog.a-foton.ru/2008/07/step-by-step-creating-connected-sharepoint-web-parts-using-iwebpartfield-interface-and-using-editor-part-and-user-controls/

  • Anonymous
    January 15, 2009
    Superb!!!!!!!!!!!!! Thanks a lot...Almost done everything for me. Now i will use usercontrols in my site. Thanks again. Kuldeep Kadyan kdk1983@gmail.com

  • Anonymous
    February 03, 2009
    This tutorial went without any flaws!! Thank you for the nice tutorial! :)

  • Anonymous
    February 09, 2009
    This was very helpful..  I ran across one issue within ContosoStandardConWP.cs I had to declare the following class variable: private string _fontName = string.Empty; and then modify the DisplayFontName property as follows: [WebBrowsable(false), Personalizable(true)]        public string DisplayFontName        {            get { return _fontName; }            set { _fontName = value; }        }

  • Anonymous
    February 23, 2009
    I FOLLOWED ALL YOUR STEP BY STEP.. ContosoConConsumerWP.cs I AM GETTING ERROR MESAGE IN THIS PAGE. ContosoStandardConConsumerWP.ContosoStandardConConsumerWP.DisplayFontName.get' must declare a body because it is not marked abstract or extern 'ContosoStandardConConsumerWP.ContosoStandardConConsumerWP.DisplayFontName.set' must declare a body because it is not marked abstract or extern

  • Anonymous
    February 28, 2009
    Excellent blog, Thank you very much...

  • Anonymous
    March 25, 2009
    Hey... Very nice Article. I had few questions. I would really appreciate if you could answer these for me. First Question: Can these connected webparts be only implemented in the Master-Child Scenario or all scenarios? What i mean is, If i had couple of other controls in the Consumer webpart like buttons which would raise events, what would be the behaviour of the webpart? Will the events be handled properly? If the answer to first question is No, then what might be the other alternative to acheive this kind of scenarios which are very common? Please send your reply to sravankasyapk@gmail.com. Thanks in Advance. Sravan Kasyap K.

  • Anonymous
    March 25, 2009
    The comment has been removed

  • Anonymous
    April 13, 2009
    I would like to know the method for creating generic web part by passing some parameters .Will that be similar to this ?

  • Anonymous
    May 30, 2010
    Great blog of sharepoint web parts. I like it. SharePoint Development is evolving with a lightning speed day by day as companies are growing. As companies grow, it is difficult to manage the record of files, documents, and their location in the companies. SharePoint Development helps you to store the files and documents and share it on a central site. <a href="http://www.sharepointengine.com">SharePoint Consulting</a>

  • Anonymous
    February 02, 2011
    please provide with screen shots.I think it is easy to go through for begineers. Thank u