Tuesday, February 26, 2013

SharePoint 2010 - Custom web part verbs

Web part verbs
The web part verbs are the menus items (like Minimize, Close etc) which appears when we click the Edit option in web parts as shown in the figure below. The SharePoint web part framework exposes one of the property called WebPartVerbCollection. This is very flexible which allows us to add our own items (custom web part verbs) to the web part collection.

Types of web part verbs
Verbs are objects of type WebPartVerb and can be of three different kinds:
1) Server-side Verbs that require a POST-back to carry out their job; they work on the server side.
2) Client-side Verbs that simply use JavaScript syntax to do their job; they work on the client side.
3) Client and server-side Verbs that first execute some client-side JavaScript, and then can execute some server-side code, unless the client-side code cancels request.

Creating a custom web part verb
1) Create a new SharePoint 2010 Project and add a classic webpart named WPCustomVerbs. Modify the CreateChildControls() event as follows and deploy the webpart.
Code Snippet
  1. protected override void CreateChildControls()
  2. {
  3.  this.Controls.Add(new LiteralControl("<h1>Custom Webparts Verbs Demo</h1>"));
  4. }

2) Following content is displayed in the webpart. Note that only default verbs are included as highlight in the following figure.

3) Now lets add the custom verb. We have to override the read-only property Verbs provided by the base WebPart class. Modified the code in webpart file as highlighted below. We have added three verbs:
i) 'Server-side verb' which will only raise a server side post-back.
ii) 'Client-side verb' which will pop up a JavaScript alert.
iii) 'Client and Server-side verb' which will raise a JavaScript alert and then a server side post-back.

Code 
public override WebPartVerbCollection Verbs
{
get
{
  // Create a Server side verb        
  WebPartVerb serverSideVerb = new WebPartVerb("serverSiteVerbId", handleServerSideVerb);
  serverSideVerb.Text = "Server-side verb";

  // Create a Client side verb 
  WebPartVerb clientSideVerb = new WebPartVerb("clientSideVerbId","javascript:alert(‘Client-side Verb selected’);");
 clientSideVerb.Text = "Client-side verb";
 WebPartVerb clientAndServerSideVerb = new WebPartVerb("clientAndServerSideVerbId", handleServerSideVerb, "javascript:alert(‘Client-side Verb selected’);");

 // Create a Client and Server side verb
 clientAndServerSideVerb.Text = "Client and Server-side verb";
 WebPartVerbCollection newVerbs = new WebPartVerbCollection(new WebPartVerb[] {
 serverSideVerb, clientSideVerb, clientAndServerSideVerb,
 });
 return (new WebPartVerbCollection(base.Verbs, newVerbs));
 }
}
Following is the complete code for WPCustomVerbs.cs
Code Snippet
  1. namespace CustomVerbsDemo.WPCustomVerbs
  2. {
  3.     [ToolboxItemAttribute(false)]
  4.     public class WPCustomVerbs : WebPart
  5.     {
  6.         protected override void CreateChildControls()
  7.         {
  8.             this.Controls.Add(new LiteralControl("<h1>Custom Webparts Verbs Demo</h1>"));
  9.         }
  10.         public override WebPartVerbCollection Verbs
  11.         {
  12.             get
  13.             {
  14.                 // Create a Server side verb        
  15.                 WebPartVerb serverSideVerb = new WebPartVerb("serverSiteVerbId", handleServerSideVerb);
  16.                 serverSideVerb.Text = "Server-side verb";
  17.  
  18.                 // Create a Client side verb
  19.                 WebPartVerb clientSideVerb = new WebPartVerb("clientSideVerbId", "javascript:alert('Client-side Verb selected');");
  20.                 clientSideVerb.Text = "Client-side verb";
  21.                 WebPartVerb clientAndServerSideVerb = new WebPartVerb("clientAndServerSideVerbId", handleServerSideVerb, "javascript:alert('Client-side Verb selected');");
  22.  
  23.                 // Create a Client and Server side verb
  24.                 clientAndServerSideVerb.Text = "Client and Server-side verb";
  25.                 WebPartVerbCollection newVerbs = new WebPartVerbCollection(new WebPartVerb[] { serverSideVerb, clientSideVerb, clientAndServerSideVerb, });
  26.                 return (new WebPartVerbCollection(base.Verbs, newVerbs));
  27.             }
  28.         }
  29.  
  30.         protected void handleServerSideVerb(Object source, WebPartEventArgs args)
  31.         {
  32.             EnsureChildControls();
  33.         }
  34.     }
  35. }

4) Deploy the web part and click on the webpart menu. You will notice that all three custom verbs are now displayed in the menu.

5) Clicking on the 'Server-side verb' link will only raise a server side post-back.

6) Clicking on the 'Client-side verb' link will pop up a JavaScript alert.

7) Clicking on the 'Client and Server-side verb' link will pop up a JavaScript alert and then raise a server side post-back.

Note
1) Usually, custom Verbs are defined in Intranet/Extranet solutions, to provide support for custom functionalities, such as refreshing content, opening custom pop-up windows, and so forth. 
2) In general, they are not used in CMS/Publishing solutions, because the context menu is usually disabled in these. 

References
1) Microsoft SharePoint 2010 Developer Reference, by Paolo Pialorsi - Book

Friday, February 22, 2013

SharePoint 2010 - Handling page display modes in webpart

Overview
As you might already know that a SharePoint webpart page can be rendered in 3 different modes:-
1) Display mode: This is the page mode when the end user is browsing the site;
2) Design mode: This is the page mode when the user can design the page layout;
3) Edit mode: This is the page mode when the end user is configuring/customizing the page and/or its controls.

WebPartManager.DisplayMode Property
To identify the page display mode and render a Web Part accordingly, you need to query the DisplayMode property of the WebPartManager (SPWebPartManager in SharePoint).

Code Sample
Lets take a closer look by creating a simple webpart and analyzing the different display modes.

1) Create an empty SharePoint project and add a classic webpart named "WPDisplayModes".

2) Write the following code in the CreateChildControls() event. Looking at the code you will observe that WebPartManager.DisplayMode Property is used to define functionality for different modes.
i) For Display mode the text will be "You are now viewing the webpart in Page Display Mode."
ii) For Design mode the text will be "You are now viewing the webpart in Page Design Mode."
iii) For Edit mode the text will be "You are now viewing the webpart in Page Edit Mode."

Code Snippet
  1. protected override void CreateChildControls()
  2. {
  3.   if (this.WebPartManager.DisplayMode == WebPartManager.BrowseDisplayMode)
  4.   {
  5.     // Page Display mode
  6.     this.Controls.Add(new LiteralControl(@"<div>You are now viewing the webpart in Page Display Mode.</div>"));
  7.   }
  8.   else if (this.WebPartManager.DisplayMode == WebPartManager.DesignDisplayMode)
  9.   {
  10.     // Page Design mode
  11.     this.Controls.Add(new LiteralControl(@"<div>You are now viewing the webpart in Page Design Mode.</div>"));
  12.   }
  13.   else if (this.WebPartManager.DisplayMode == WebPartManager.EditDisplayMode)
  14.   {
  15.     // Page Edit mode
  16.     this.Controls.Add(new LiteralControl(@"<div>You are now viewing the webpart in Page Edit Mode.</div>"));
  17.   }
  18. }

3) Deploy the webpart. Open the target webpart page in Edit Mode and add the webpart.

4) The webpart page's initial mode will be Design mode, therefore the text displayed in the webpart will be "You are now viewing the webpart in Page Display Mode".

5) Click the webpart menu and choose Edit Web Part.

6) Now the webpart page's mode will be Edit mode, therefore the text displayed in the webpart will be "You are now viewing the webpart in Page Edit Mode."

7) Select "Stop Editing" button on the top-left corner of the page for rendering the page in Display Mode.

8)  Now the webpart page's mode will be Display mode, therefore the text displayed in the webpart will be "You are now viewing the webpart in Page Display Mode."




Wednesday, February 20, 2013

SharePoint 2010 - Creating Custom Editor Parts

Overview
In the previous post we discussed how we can create configurable webpart properties. We also noticed that the web part properties were ENUM and we could only enter static values as parameter like typing a list name or column name etc.What if you type the list name incorrectly? Therefore, you would want to choose a list from a asp.net dropdown containing all the available lists and display the items for the selected list in a Gridview. This is were EditorParts come in handy! So lets get started...

Editor Parts
To customize the Web Parts’ configuration user interface you can create custom classes called Editor Parts which are controls hosted in a specific WebPartZone called EditorZone.
ASP.NET 2.0 contains an abstract class called EditorPart, this class is used with the ASP.NET 2.0 WebPart class to create customized tool panes. By inheriting from this control you can customize the look and functionality of the tool pane and use standard ASP.NET constructs such as auto post backs, validations etc.

IWebEditable Interface
To provide a Web Part with a custom Editor Part, you need to override the implementation of the IWebEditable interface, which is implemented by the Web Part base class.

Steps for creating an Editor Part

1) Open Visual Studio and create a new Visual Web Part named MyVisualWP. In the "MyVisualWpUserControl.ascx" add a GridView control name "gvwProducts".



2) Go to the webpart file "MyVisualWP.cs" and add a property named "ListName".
public string ListName { getset; }

3) Now add a new class named "WPEditor.cs" which inherits from the "EditorPart" class.
i) Create a DropDownList named "ddlList" and populate the List Names. Add ddlList to the controls collection
ii) Override Apply Changes() : This method is used to save any changes to the currently-edited Web Part.
iii) Override SyncChanges()   : This method is used to load the current configuration from Web Part Properties.

Following is the complete code for WPEditor.cs
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web.UI.WebControls.WebParts;
  6. using System.Web.UI.WebControls;
  7. using Microsoft.SharePoint;
  8. using System.Web.UI;
  9.  
  10. namespace VisualWebpartDemo.MyVisualWP
  11. {
  12.     public class WPEditor : EditorPart
  13.     {
  14.         private DropDownList ddlList;
  15.         protected override void OnInit(EventArgs e)
  16.         {
  17.             base.OnInit(e);
  18.             ddlList = new DropDownList();
  19.             SPWeb oWeb = SPContext.Current.Web;
  20.             foreach (SPList oLists in oWeb.Lists)
  21.             {
  22.                 ddlList.Items.Add(oLists.Title);
  23.             }
  24.         }
  25.  
  26.         protected override void CreateChildControls()
  27.         {
  28.             base.CreateChildControls();
  29.             this.Controls.Add(new LiteralControl("My List Name<br/>"));
  30.             this.Controls.Add(ddlList);
  31.             this.Controls.Add(new LiteralControl("<br/>"));
  32.         }
  33.  
  34.         protected override void OnPreRender(EventArgs e)
  35.         {
  36.             base.OnPreRender(e);
  37.         }
  38.  
  39.         public override bool ApplyChanges()  //ApplyChanges is used to save any changes to the currently-edited Web Part.
  40.         {
  41.             MyVisualWP webPart = this.WebPartToEdit as MyVisualWP;
  42.             if (webPart != null)
  43.             {
  44.                 webPart.ListName = ddlList.SelectedValue;
  45.             }
  46.             return true;
  47.         }
  48.  
  49.         public override void SyncChanges()  // SyncChanges is used to load the current configuration from Web Part Properties.
  50.         {
  51.             MyVisualWP webPart = this.WebPartToEdit as MyVisualWP;
  52.             if (webPart != null)
  53.             {
  54.                 ddlList.SelectedValue = webPart.ListName;
  55.             }
  56.         }
  57.     }
  58. }

4) Make the following changes in the user controls code behind file "MyVisualWPUserControl.ascx.cs" which nothing but passing the "ListName" property that we created in above steps as parameter to the Gridview.
Code Snippet
  1. namespace VisualWebpartDemo.MyVisualWP
  2. {
  3.     public partial class MyVisualWPUserControl : UserControl
  4.     {
  5.         public MyVisualWP objMyVisualWP { get; set; }
  6.         protected override void OnPreRender(EventArgs e)
  7.         {
  8.             base.OnPreRender(e);
  9.             if (this.objMyVisualWP.ListName != null)
  10.             {
  11.                 SPWeb oWeb = SPControl.GetContextWeb(HttpContext.Current);
  12.                 SPList oList = oWeb.Lists[this.objMyVisualWP.ListName];
  13.                 SPListItemCollection oColl = oList.Items;
  14.                 gvwProducts.DataSource = oColl.GetDataTable();
  15.                 gvwProducts.DataBind();
  16.             }
  17.         }
  18.     }
  19. }

5) Now, go back to the webpart file "MyVisualWP.cs" and implement the "IWebEditable" interface.


6) Override the "CreateEditorParts()" method which returns an EditorPartCollection. In this method we will add our custom EditorPart "WPEditor.cs" to the EditorPartCollection.
public override EditorPartCollection CreateEditorParts()
{
  List<EditorPart> editorParts = new List<EditorPart>();
  WPEditor oWPEditor = new WPEditor();
  oWPEditor.ID = this.ID + "_sampleEditorPart";
  oWPEditor.Title = "Personalize";
  editorParts.Add(oWPEditor);
  return new EditorPartCollection(base.CreateEditorParts(), editorParts);
}


Following is the complete code for MyVisualWP.cs
Code Snippet
  1. namespace VisualWebpartDemo.MyVisualWP
  2. {
  3.     [ToolboxItemAttribute(false)]
  4.     public class MyVisualWP : WebPart, IWebEditable
  5.     {
  6.         public string ListName { get; set; }
  7.  
  8.         // Visual Studio might automatically update this path when you change the Visual Web Part project item.
  9.         private const string _ascxPath = @"~/_CONTROLTEMPLATES/VisualWebpartDemo/MyVisualWP/MyVisualWPUserControl.ascx";
  10.  
  11.         protected override void CreateChildControls()
  12.         {
  13.             MyVisualWPUserControl control = Page.LoadControl(_ascxPath) as MyVisualWPUserControl;
  14.             control.objMyVisualWP = this;
  15.             Controls.Add(control);
  16.         }
  17.  
  18.         public override EditorPartCollection CreateEditorParts()
  19.         {
  20.             List<EditorPart> editorParts = new List<EditorPart>();
  21.             WPEditor oWPEditor = new WPEditor();
  22.             oWPEditor.ID = this.ID + "_sampleEditorPart";
  23.             oWPEditor.Title = "Personalize";
  24.             editorParts.Add(oWPEditor);
  25.             return new EditorPartCollection(base.CreateEditorParts(), editorParts);
  26.         }
  27.  
  28.         object IWebEditable.WebBrowsableObject
  29.         {
  30.             get { throw new NotImplementedException(); }
  31.         }
  32.     }
  33. }

7) Deploy the solution and add the webpart to the page in edit mode. You can see that there is a dropdownlist in the webpart properties window with all the lists. Choose any of the list and click 'Apply' or 'Ok' button.

8) The Gridview will be populated with the items in the list that you selected in the dropdownlist.

So that was all about custom EditorParts in webparts! Keep reading!

Tuesday, February 12, 2013

SharePoint 2010 - Configurable Web Part Properties

In  the previous post, we created a Visual Webpart using visual studio. In this post we will discuss about web part properties and how to create configurable web part properties.

WebPart Properties
All Web Parts share a set of common properties that allow you to specify attributes for the appearance, layout, and other information. To view web part properties, click on the web part menu and select Edit web part".

On the right hand side you can see the web part properties window opens. Here you can make the basic changes like adjusting height, width, Title, etc.


Configurable WebPart Properties
Apart from the default properties, you may want to add you own custom properties which can be even used as parameters for the webpart. Configurable Web Parts are used to present a user-friendly interface for Web Parts configuration. The following attributes makes it possible to add custom properties.

The WebBrowsableAttribute class
The WebBrowsableAttribute class instructs the Web Parts infrastructure that the property has to be made available in the Web Part’s configuration panel. 

The PersonalizableAttribute class
The PersonalizableAttribute declares that the property can be personalized and defines the scope of the personalization. There 2 types of scopes:
1) Scope of type User, which means that the property can be personalized on a per-user basis.
2) Scope of type Shared, which means that the property personalization will be shared between all users.

Configurable WebPart Attributes
Following attributes enables the display of the custom properties in web part properties window.
1) [WebBrowsable(true)] - This will hide or show the property on the tool pane.
2) [Personalizable(PersonalizationScope.Shared)] - How the WebPart is configured, which can be per-user (PersonalizationScope.User), or for everyone (PersonalizationScope.Shared). 
3) [WebDescription("Description of List")] - Description for the property.
4) [WebDisplayName("My List Name")] - Label for the property.
5) [Category("Personalized Items")] - This will group your property according to category. If not declared, “Miscellaneous” will be used as the default.
6) [DefaultValue("Default")] - The default value for the property.

 Following are the steps for creating a Configurable Web Part Property :
1) Create two custom lists as follows:
i) "Products" with columns "Title", "Description" and "Price".
ii) "Customers" with columns "Title" and "Address".

2) Open Visual Studio and create a new Visual Web Part named MyVisualWP. In the "MyVisualWpUserControl.ascx" add a GridView control name "gvwProducts".

3) Open the solution in visual studio and modify the code in the Webpart file "MyVisualWP.cs" as follows. i) Add a configurable web part property named "ListName" using [WebBrowsable] attribute.
ii) Modify the CreateChildControls() to change the type of Control to Visual Web Part.
Following is source code for MyVisualWP.cs
Code Snippet
  1. namespace VisualWebpartDemo.MyVisualWP
  2. {
  3.     [ToolboxItemAttribute(false)]
  4.     public class MyVisualWP : WebPart
  5.     {
  6.  
  7.         [WebBrowsable(true),
  8.         Category("Personalize"),
  9.         WebDisplayName("List Name"),
  10.         WebDescription("Custom list name editable by user")]
  11.         [Personalizable(PersonalizationScope.Shared)]
  12.         public string ListName { get; set; }
  13.  
  14.         // Visual Studio might automatically update this path when you change the Visual Web Part project item.
  15.         private const string _ascxPath = @"~/_CONTROLTEMPLATES/VisualWebpartDemo/MyVisualWP/MyVisualWPUserControl.ascx";
  16.  
  17.         protected override void CreateChildControls()
  18.         {
  19.             MyVisualWPUserControl control = Page.LoadControl(_ascxPath) as MyVisualWPUserControl;
  20.             control.MyVisualWebpart = this;
  21.             Controls.Add(control);
  22.         }
  23.     }
  24. }

4) Now, go to the user control code behind file "MyVisualWPUserControl.ascx.cs" and modify code as highlighted below.
i) You will notice that we added a public property for getting the web part.
ii) Then we use the "ListName" property of the web part to specify the list name.
iii) We set the ViewFields property in the SPQuery object to display titles: Title", "Description", "Price"
and "Address".
Following is source code for MyVisualWPUserControl.ascx.cs
Code Snippet
  1. namespace VisualWebpartDemo.MyVisualWP
  2. {
  3.     public partial class MyVisualWPUserControl : UserControl
  4.     {
  5.         public MyVisualWP MyVisualWebpart { get; set; }
  6.         protected void Page_Load(object sender, EventArgs e)
  7.         {
  8.             if (MyVisualWebpart.ListName != null)
  9.             {
  10.                 SPSite oSite = SPContext.Current.Site;
  11.                 using (SPWeb oWeb = oSite.OpenWeb())
  12.                 {
  13.                     SPQuery oQuery = new SPQuery();
  14.                     oQuery.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='Description' /><FieldRef Name='Price' /><FieldRef Name='Address' />";
  15.                     oQuery.ViewFieldsOnly = true;
  16.                     SPList oList = oWeb.Lists[MyVisualWebpart.ListName];
  17.                     SPListItemCollection oColl = oList.GetItems(oQuery);
  18.                     gvwProducts.DataSource = oColl.GetDataTable();
  19.                     gvwProducts.DataBind();
  20.                 }
  21.             }
  22.         }
  23.     }
  24. }

5) Deploy the solution and open the web part page in edit mode. 

6) Go to the web part properties and you can see the new custom property that we added.


7) Enter the list name "Products" and click "Apply" button, you will see the items in the Products List are populated in the GridView.

8) Now change the List Name to "Customers" and click "Apply" button. You will see the items in the Customers list will be populated in the GridView.

Note:- The above code defined property that requires the end user to configure the Web Part manually, typing the target list name autonomously and  made use of the standard behaviour of SharePoint and the out-of-the-box CustomPropertyToolPart.
But this is not a user-friendly and error-free approach. The right solution would probably be to provide a drop-down list with all the lists available in the current website, thereby avoiding typo errors and the consequent time consuming debugging tasks.
To customize the Web Parts’ configuration user interface you can create custom classes called "Editor Parts" which are controls hosted in a specific WebPartZone called EditorZone.

We will take a closure look on to Editor Parts in the next post

Thursday, February 7, 2013

SharePoint 2010 - Creating a Visual Webpart

Overview
Visual webparts wraps asp.net user control inside a classic webpart, so that programmer could work on ascx file as for any other web project instead to have to resort to programmatically create the controls via the CreateChildControl method.Visual webparts evolved in SharePoint 2010 and can be used for easily creating webparts with rich UI. But the performance is somewhat less compared to classic webparts, since there is an overhead of loading the user controls.

Creating a Visual Webpart
Following are the steps for creating a Visual Webpart.

1) Open Visual Studio and select "New Project->SharePoint->2010". The following window will open displaying all SharePoint project templates. Select "Empty SharePoint Project", give a suitable name and click "Finish".

2) The following window pops-up just like in classic web parts. Enter the suitable Site collection name for debugging purpose and click the "Finish" button..
Note: Sandboxed Solution option will be disabled since visual web parts can be created only in Farm Solution.

3)  Just like Classic web parts,when a web part is added 2 main components are added.
i) First one is the Web Part "MyVisualWP" which contains all the files supporting the web part. The difference is that that a "User Control" will be wrapped inside the Web part and rendered in the "CreateChildControl()" event.
ii) Second one is "Features" contains the features for deploying the web part to the site.
(Note: We will take a closer look into "Features" in the upcoming posts.)

4) In the "MyVisualWpUserControl.ascx" user control add an asp.net "Label" control as follows:

5) Build the solution and go to bin->Debug folder in the project. You will see a ".wsp" file which is the solution package for the Visual Web Part.


6) Select "Build-> Deploy MyVisualWebPart" to deploy the webpart to the site collection that we entered in the "SharePoint Customization Wizard" in the 2nd step.
(Note: For deploying the wepart solution to another site collection or subsite we must use the STSADM command line tool or SharePoint Management Shell. We will discuss deployment in detail in the upcoming sessions.)

7) Now open the Web part page in "Edit mode" and click "Add a Web Part". The web part "My Visual Webpart" is now available in the web part gallery under "Custom" group. Select the web part and click "Add".

8) Our web part has been created and displays the label that we added in the User Control.

9) Go to 14 Hive->TEMPLATE->CONTROLTEMPLATES-MyVisualWebpart->MyVisualWP. You will see the user control that we created has been deployed in this location.

10) Now, lets try to display the following list items from a list named "Products" using a asp.net GridView in the user control.

11) Add a GridView control name "gvwProducts".

12) Write the following code in the Page_Load event for fetching list items and binding to the GridView.
SPSite oSite = SPContext.Current.Site;
            using (SPWeb oWeb = oSite.OpenWeb())
            {
                SPList oList = oWeb.Lists["Products"];
                SPListItemCollection oColl = oList.GetItems();
                gvwProducts.DataSource = oColl.GetDataTable();
                gvwProducts.DataBind();
            }


13) Deploy the solution as in Step 6 and refresh the existing web part page. You can see the list items have been fetched and display through GridView.
Note: You might see some additional columns generated which are default SharePoint columns in the List.

To display just the required columns, you can use an "SPQuery" as follows

14) Modify code in the Page_Load event for fetching only the column that we want.
SPSite oSite = SPContext.Current.Site;
            using (SPWeb oWeb = oSite.OpenWeb())
            {
                SPQuery oQuery = new SPQuery();
                oQuery.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='Description' /><FieldRef Name='Price' />";
                oQuery.ViewFieldsOnly = true;
                SPList oList = oWeb.Lists["Products"];
                SPListItemCollection oColl = oList.GetItems(oQuery);
                gvwProducts.DataSource = oColl.GetDataTable();
                gvwProducts.DataBind();
            }


15) Now you can see that the GridView displays the items in the "Products" list with only the column that we choose to display.

Hope this post is helpful to you. Thanks!