1

SharePoint 2007 Site Templates vs. Site Definitions


There is an ongoing debate between SharePoint developers regarding the best approach for packaging and deploying customized SharePoint solutions.
One easy approach is to use site templates, but my opinion is that for a developer who are concerned about system performance and who needs finer control over cusomization, a site definition is the better option.

I found that building some sort of custom site provisioning provider works the best.

Below is my analysis of the differences between site definitions vs. site templates and at the bottom is a summary of the approach I prefer for deploying custom SharePoint solutions.

What is a Site Definition?
A Site definition is the core definition of what a site is in SharePoint.
User content on a SharePoint site is located in a SQL Server database.
All the code and the pages that are used to administer and render the SharePoint site are stored as physical files on the web server.
A site definition exists as physical files on the web server and defines, through the use of SharePoint’s XML schema (known as CAML), the lists, columns, features etc. that should be created / activated when a site is created. (The files includes .aspx pages and .xml files)
A site definition is installed on file system of web front ends, located at ..\12\Template\SiteTemplates. This directory is language-neutral.
Site definition files are cached in memory on the server at process start-up of Microsoft Internet Information Services (IIS), which improves scalability and performance by reducing unnecessary data storage or retrieval, and by allowing uncustomized pages to be reused across sites. The information contained in these files is pulled from the cache at run time. Pages and list schemas are read from the site definition files but appear to be actual files within a site.
 
What is a Site Template?
A site template (*.stp file) is created through the user interface or through implementation of the object model. It is a package containing a set of differences and changes from a base site definition.
The site template package is stored as a CAB-based file that can be downloaded or uploaded to site collections by users with the appropriate rights.
It is not as performant as a pure site definition as site definitions are cached on start of IIS on the web front ends while site templates are stored and hence need to be fetched from the content database and merged with the site definition code at runtime to render the site.


Deciding Between Site Definitions and Custom Site Templates
 
Site Templates

  • Easy to create.
  • You do not need to be a server administrator on the Web server to create and deploy site templates.
  • Easiest way for system administrators to extend SharePoint without requirement for development skills.
  • Deployment is simple because template data is stored centrally in the configuration database.
  • Because it is slow to store templates in and retrieve them from the database, site templates can result in slower performance.
  • The contents of unghosted pages are routed through the Safe Mode parser, which prevents server-side code from executing, and which depends entirely on the Safe Controls list specified in the web.config file of the wwwroot directory to determine which controls can be rendered at run time.
  • You can modify a site template without affecting existing sites created by the template.
  • Custom templates can be modified without affecting existing sites that have been created from the templates.
  • Custom templates are not created in a development environment.
  • If the site definition on which the custom template is based does not exist on the front-end server or servers, the custom template will not work.
  • If you plan to transfer a site template to separate farm, that the farms have the same versions installed of SharePoint installed. (hotfixes,etc.) This is due to the dependence site templates have on the original base site definition they were created from.
Site Definitions:
  • Complex and laborious to create.
  • Administrators must always be involved in the deployment of site definitions.
  • Most appropriate for third-party developers.
  • Deploying a site definition requires more work.
  • Site definition files are cached in memory on the server at process start-up of Microsoft Internet Information Services (IIS), which improves scalability and performance by reducing unnecessary data storage or retrieval.
  • Uncustomized pages to be reused across sites.
  • You can achieve a finer level of customization by directly editing all the schema files.
  • Custom site definitions are version and upgrade independent.
  • Subsequent upgrades to SharePoint Products and Technologies may overwrite existing default site definitions. Using custom site definitions excludes your sites from potential upgrade issues.
  • There is no easy way to modify site definitions once they are deployed
  • Doing anything other than adding code can break existing sites
  • Users cannot apply a SharePoint theme through a site definition.
  • Customizing site definitions requires access to the file system of the front-end Web server.
  • Multiple root-level pages -- In a site definition, you can define several root-level pages. Instead of your sites having one page, they can have many.
  • Template picker pages -- You have the ability to change the icon that displays in conjunction with the template so it stands out as you create the templates.
  • Microsoft doesn't support changes made to a site definition after you've created the sites.
  • Multiple lists of the same type -- Because of the structure of CAML and the ONET.XML file, you can't create multiple lists from the same list definition and put them on the same page.
Summary of my preferred approach:
I found that building a custom site provisioning provider works the best.
This means that I build my SharePoint artefacts - lists, libraries, web parts, custom forms, etc. using SharePoint, SharePoint Designer and Visual Studio. When I am then ready to package and deploy my custom SharePoint solution I use the SharePoint Solutions Generator - part of Microsoft SharePoint Developer Tools 9.0 to create list and library definition features.
Once I have my list and library definitions in place I create a Visual Studio WSP Builder project with an Feature Event Receiver.
In the "activate" event I add logic to activate the definition features and in the "deactivating" event I do a cleanup (deactivate definition features and remove web parts)


This means the following will happen when one of my solutions are deployed / retracted:
1. The user creates a blank SharePoint site. (previously team site)
2. The user runs a Setup.exe file.
3. This file is the un-customized Codeplex Solutions Installer and will read configuration data from Setup.exe.config
4. The file will open a deployment wizard which guides the user through a series of screens to ensure successful solution deployment.
5. After successful deployment the user follow instructions from the deployment guide to execute a single stsadm.exe command.
6. This command will activate a single hidden feature.
7. The single feature which gets activated will do the following on the site:
  • Set the new site title.
  • Check environment for previously installed features which are still active
  • Activate Web Features in the correct order 
  • Activate Site Collection Features
  • Allows activation of generic site collection features – shared among more than 1 solution.
  • Clear Site Structure – remove unwanted artefacts
  • Set Site Structure – build Quick Launch Items, Set Web Parts on Default.aspx page etc.
8. During deactivation of the single “configuration” feature the following will happen:
  • Set the new site title back to default.
  • Deactivate Web Features in the correct order 
  • Deactivate Site Collection Features
  • Clear Site Structure – remove unwanted artefacts
  • I do not delete lists or libraries which contain data – do not want to delete data.
Benefits of this approach:
  • Allows dependencies between hidden features - lookup lists
  • Allows list to be automatically instantiated with default data
  • Allows library content – like UDCX files to be configured with new environmental values (link InfoPath Form to dynamic data connections)
  • Allows activation of web part features to site collection scope
  • Allows validation and upload of InfoPath Forms (using site collection feature)
  • Allows publishing of InfoPath Form to site collection forms library
  • Leverage off the benefits of using definitions. 

I hope this will help you to choose the best approach for the kind of SharePoint solutions which you need to deploy... good luck !!


Further reading and references:
http://itfootprint.wordpress.com/2007/04/18/sharepoint-site-template-vs-site-definition/
http://msdn.microsoft.com/en-us/library/ms980852.aspx
http://mymemorysucks.wordpress.com/2009/02/25/site-definitions-vs-site-templates-and-site-provisioning-providers/
http://my.advisor.com/doc/17614
http://blogs.msdn.com/b/brianwilson/archive/2008/07/13/site-definitions-versus-site-templates-and-deciding-on-the-correct-customization-approach.aspx

12

SharePoint 2010 Provider Consumer Web Parts

In this tutorial I will show how to develop Provider and Consumer web parts and connect them through an Interface.
The result will be the ability to have two web parts on a SharePoint 2010 page and filter the contents of the consumer web part on the data from the provider web part. This is almost like a master - detail view.
You can view the same functionality by looking at the standard SharePoint web parts. Modify a web part --> select Connections and the "Provide data to..." or "Receive data from..."

and then...













Lets Get Started:
I will show the detailed steps to:
1 - Develop a Connection Interface
2 - Develop a simple provider web part.
3 - Develop a simple consumer web part.

1 - Develop a Connection Interface.

Open Visual Studio 2010 and create a new project. In the New Project dialog window, select Visual C# --> SharePoint 2010 --> Empty SharePoint Project.
Provide a descriptive name and click on OK.
Select to deploy the solution as a "Deploy as Farm Solution" and click on Finish.
Wait for the solution to be created in Visual Studio.


Now we will create the web part connection interface which is responsible for exchanging connection information between a provider and consumer web part.
In the Solution Explorer, right-click on your project and select "Add --> New item".
In the Add New Item dialog window, select Visual C# --> Code --> Interface.
Enter ITask in the Name textbox and click the Add button.
Open ITask.cs in code view and change the visibility of the interface to Public and add the following code inside the interface:
namespace WebPartConnectors
{
   public interface ITask
   {
      int Id { get; }
      string Name { get; }
   }
}

2 - Develop a simple provider web part:
In the Solution Explorer, right click on your project and select Add --> New Item…
Select Visual C# --> SharePoint 2010 Web Part.
Enter ProviderWebPart in the Name textbox and click Add.
Open ProviderWebPart.cs in code view and in the ProviderWebPart class declaration, implement ITask.
public class ProviderWebPart : Microsoft.SharePoint.WebPartPages.WebPart, ITask


Insert the following code after the ProviderWebPart class declaration.
This code block implements the ITask web part connection interface and adds a local variable to the web part.
DropDownList _objPicker = null;
int ITask.Id
 {
    get
    {
     return int.Parse(_objPicker.SelectedValue);
    }
 }
string ITask.Name
 {
   get
   {
     return _objPicker .SelectedItem.ToString();
   }
 }

Update the CreateChildControls method to contain the following code:

protected override void CreateChildControls()
{
  try
  {
    _objPicker= new DropDownList();
    using (SPSite spSite = new SPSite(SPContext.Current.Web.Url))
    using (SPWeb spWeb = spSite.OpenWeb())
    {
      SPList objList = spWeb.Lists["Tasks"];

      foreach (SPListItem objListItem in objList.Items)
      {
        _objPicker.Items.Add(new ListItem(objListItem.Title, objListItem.ID.ToString()));
      }    
     }
     _objPicker.AutoPostBack = true;
     this.Controls.Add(_objPicker);
  }
  catch (Exception ex)
  {  
    this.Controls.Clear();
    this.Controls.Add(new LiteralControl(ex.Message));
  }
}

Insert the following ConnectionProvider property below the CreateChildControls method. This provides the Connection Provider interface point for the ProviderWebPart: [ConnectionProvider("Task Name and ID")]
public ITask NameDoesNotMatter()
{
  return this;
}


Save your solution and build. Ensure that there are no build errors before you proceed.


3 - Develop a simple consumer web part.
In the Solution Explorer, right click on your project and select Add --> New Item…


Select Visual C# --> SharePoint 2010 Web Part.
Enter ConsumerWebPart in the Name textbox and click Add.


Insert the following code inside the ConsumerWebPart class declaration:
ITask _provider = null;
Label _lbl = null;

Update the CreateChildControls method to contain the following code:
protected override void CreateChildControls()
{
try
{
_lbl = new Label();
if (_provider != null)
{
if (_provider.Id > 0)
{
_lbl.Text = _provider.Name + " was selected.";
}
else
{
_lbl.Text = "Nothing was selected.";
}
}
else
{
_lbl.Text = "No Provider Web Part Connected.";
}
this.Controls.Add(_lbl);
}
catch (Exception ex)
{
this.Controls.Clear();
this.Controls.Add(new LiteralControl(ex.Message));
}
}

Insert the following ConnectionConsumer property below the CreateChildControls method. This provides the Connection Consumer interface point for the ConsumerWebPart:[ConnectionConsumer("Name and ID")]
public void ThisNameDoesNotMatter(ITask providerInterface)
{
  _provider = providerInterface;
}

Save the solution, Build the solution and Deploy the solution.
Go to your target SharePoint 2010 site and refresh the site.
Edit a page and add the two new web parts.(ensure that you have some data in the SharePoint Tasks list)















View your two new web parts on the page:






















Edit the page again and select the ProviderWebPart and click on Edit Web Part.















Select the ProviderWebPart again, but this time select "Connections" --> "Send Task Name and ID To" --> ConsumerWebPart.



Now, if you select an item from the dropdown list control in the providerwebpart you will see the corresponding data change in the consumerwebpart.













This way you will be able to build master-detail views or web part filters based on selections of other web parts.

Enjoy !!

3

Basic SharePoint 2010 LINQ Web Part

In this tutorial I will show how to develop a very basic visual web part which uses LINQ (LINQ to SharePoint) to populate data from a SharePoint 2010 list into a SPDataGrid control.

The web part will look like this:

Overview:
The following steps will be taken to develop the web part which contains LINQ.
1- Create a Visual Web Part.
2- Create a LINQ proxy class.
3- Use a LINQ provider to read data from a SharePoint list.
4- Show the data in a SPDataGrid control.

Lets get started
1- Create a Visual Web Part:

Create a new Visual Studio 2010 project. From the installed templates select Visual C# --> SharePoint --> 2010 --> Visual Web Part.
Provide a suitable name and click on OK.
















Select to deploy the solution as a Farm Solution and click on "Finish"



Once the project is created, open the VisualWebPart1.webpart (from the solution explorer)
Change the Title and Description values and save the file.
<properties>

<property name="Title" type="string">MyFirstSPLinqWebPart</property>
<property name="Description" type="string">My First SQL LINQ Web Part</property>
</properties>

2- Create a LINQ proxy class.
In the Solution Explorer, right-click on your project and select Open Folder in Windows Explorer.

Hold Shift key and right click anywhere in the Explorer Window and select Open Command Window Here to open the command prompt window in the current project directory.















Type the following command in the command prompt and press Enter to set the path to the SharePoint 2010 folder:

set path=%path%;c:\program files\common files\microsoft shared\web server extensions\14\bin

Type the following command in the command prompt and press Enter to generate the Linq-to-SharePoint proxy code.
the yoursharepointsiteaddress value should reflect the URL of your SharePoint 2010 site.
(mine was http://svr-x:12345/)
For yourwebpartnamespace value I used MyFirstSPLinqWebPart.VisualWebPart1.
spmetal.exe /web:http://yoursharepointsiteaddress /namespace:yourwebpartnamespace /code:SPLinq.cs
so my command looked like:
spmetal.exe /web:http://svr-x:1234 /namespace:MyFirstSPLinqWebPart.VisualWebPart1 /code:SPLinq.cs


Note – you may get warnings about content types for list Form Templates. You can safely ignore this warning and continue.
Close the command window and switch back to Visual Studio.
In Visual Studio, in the solutions explorer, right click on your project and select Add Existing Item --> Navigate to the SPLinq.cs file (should be in your project folder)..select the file from the Add Existing Item dialog window and click Add.
 
Next we will add a reference to Linq to our project.
In the Solution Explorer right click on References and click on "Add Reference".
Select Microsoft.SharePoint.Linq from the list of .net references and click on OK.
(the file is available on the server as C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.Linq.dll)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3- Use a LINQ provider to read data from a SharePoint list & populate the GridView:

In Solution Explorer, expand VisualWebPart1 and double-click on VisualWebPart1UserControl.ascx.

Add the following code to the bottom of the file below the code which already exists in the file..
This is to generate the user control to construct the grid view.
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<SharePoint:SPGridView id="spGridView" runat="server" AutoGenerateColumns="false">
     <HeaderStyle HorizontalAlign="Left" ForeColor="Navy" Font-Bold="true" />
         <Columns>
             <SharePoint:SPBoundField DataField="Title" HeaderText="Title"></SharePoint:SPBoundField>
             <SharePoint:SPBoundField DataField="Body" HeaderText="Body"></SharePoint:SPBoundField>
             <SharePoint:SPBoundField DataField="AssignedTo" 
                                 HeaderText="AssignedTo"></SharePoint:SPBoundField>
         </Columns>
</SharePoint:SPGridView>

In the Solution Explorer, right click on VisualWebPart1UserControl.ascx and select View Code. Add the following using statements to the code behind: 
using Microsoft.SharePoint.Linq;

using Microsoft.SharePoint;
using System.Linq;
Insert the following code inside the Page_Load method:
SPLinqDataContext dc = new SPLinqDataContext(SPContext.Current.Web.Url);

EntityList<Task> Tasks = dc.GetList<Task>("Tasks");
var empQuery = from taskitem in Tasks
      select new
      {
          taskitem.Title,
          Body = taskitem.Body,
          taskitem.AssignedTo,
      };
spGridView.DataSource = empQuery;
spGridView.DataBind(); 

Build the project and deploy.
Refresh your SharePoint site.
Edit an existing page and add your new web part to the page (select your new web part)
















You will now see the data which is loaded from a SharePoint list using LINQ and represented in a SPDataGrid.













Enjoy !!

1

SharePoint 2010 Ribbon Custom Command

In this last tutorial I show how to create a Web Part which adds a command to the Ribbon. This is an introduction to customizing the SharePoint 2010 Ribbon using custom actions.



Lets get started:
Create a new Visual Studio 2010 Project.
Select SharePoint and then Empty SharePoint Project.
Name the project and click on OK 
Specify the site to use for debugging, select "Deploy as farm solution" and click on Finish.
 
Using the Solution Explorer, add a new item to the project.
Select Visual C# --> SharePoint 2010 --> Empty Element.
Name the element RibbonActions and click on "add"


 In the editor for the Elements.xml file that has opened automatically add a new <CustomAction> element right inside the <Elements> node and add the following markup. (your project will contain two Elements.xml files. One under MyRibbonWebPart and another under RibbonActions. The changes required here is for the Elements.xml file under RibbonActions)


<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="Hello_world"
    RegistrationType="List"
    RegistrationId="101"
    Location="CommandUI.Ribbon"
    Sequence="5">
    <CommandUIExtension>
       <CommandUIDefinitions>
         <CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children">
            <Button
               Id="Ribbon.Documents.HelloWorldButton"
               Alt="Hello World"
               Sequence="5"
               Command="Show_HelloWorld"
               Image32by32="/_layouts/images/placeholder32x32.png"
               LabelText="Hello World Command"
               TemplateAlias="o1"/>
          </CommandUIDefinition>
      </CommandUIDefinitions>
  
    <CommandUIHandlers>
      <CommandUIHandler
        Command="Show_HelloWorld"
        CommandAction="javascript:alert('Hello World!');" />
      </CommandUIHandlers>
    </CommandUIExtension>

 </CustomAction>
</Elements>

Save the project and build the project.
In the Solution Explorer, right-click on the project and choose Deploy.
 
Open the web.config file of the web application which hosts the SharePoint site which you deployed to.
Add a SafeControls entry for the new assembly.(remember that your PublicKeyToken value will be different)
<SafeControl Assembly="MyRibbonWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3d7d18f076284cdb" Namespace="MyRibbonWebPart.MyRibbonWebPart" TypeName="*" Safe="True" AllowRemoteDesigner="True" />

Save and close the web.config file.
Navigate to the target SharePoint Site, go to Site Actions -->Site Settings --> Manage Site Features and activate the new feature.

Navigate to a document libary and click on "Documents" group in the Ribbon. Notice the new action item.


Click on the new custom action to view execution of the javascript.


Enjoy !!

1

Nintex Workflow 2010 Installation

Today I installed and configured Nintex Workflow 2010 for SharePoint 2010.

I must say, the guys at Nintex are doing a brilliant job and their product documentation is clear and easy to follow.
I had absolutely no problems installing Nintex Workflow 2010 on my SharePoint 2010 sandbox and this tutorial will show how easy it is to prepare a Nintex Workflow 2010 environment.

The reasons for choosing Nintex Workflow 2010 as a workflow designer tool deserve a separate post, but for a quick overview please have a look at this site.

Prerequisites:
In my environment I had the following in place before installing Nintex Workflow 2010:
  * Windows 2008 Server
  * Microsoft Office SharePoint Server 2010
  * SQL Server 2008 (and other prerequisites to run SharePoint 2010)
  * SMTP Server (outside of the SharePoint Farm)
  * SMTP Service configured on Windows 2008 server (see instructions)
  * Outgoing email settings configured for SharePoint Farm (see instructions)
  * Outgoing email settings configured for SharePoint Web App (see instructions)

Installation & Configuration:
The install is very simple.
I followed the installation guide which is available on this site under technical information.

The following steps need to be followed:
  1 Install the Nintex Workflow 2010 solution package
  2 Perform Database Configuration
  3 Configure Workflow Server Settings
  4 Activate Features

1 Install the Nintex Workflow 2010 (NW2010) solution package:
To install the NW2010 solution package is really very easy.
Ensure that you are logged in to the server as local admin.

  1.1 Run the NintexWorkflow2010.msi from the local machine.
        Follow the steps through the wizard until finished.
 
I got a error during installation complaining that the assembly failed in the zone "My Computer"
To solve this make sure that User Account Control is turned off or set it to the very minimum.
Follow these steps:
  1.Click on Start, and then Control Panel
  2.In Control Panel, click User Accounts
  3.In the User Accounts window, click User Accounts
  4.In the User Accounts tasks window, turn the User Account Control to the very minimum
  5.Restart to apply the changes



  1.2 Deploy the solution to web applications.
       Open the SharePoint 2010 Central Administration 
       go to 'System Settings' and then to 'Manage Farm Solutions'
       You will see 2 new solutions in the list of solutions in the farm.
       They are:
         nintexworkflow2010.wsp and
         nintexworkflow2010enterprisefeatures.wsp
       Deploy both solutions to all content web applications.
       After both solutions have been deployed successfully you should see the following 
       status:

       In order to activate the NW2010 configuration functionality in Central Admin, you
       have to deploy the nintexworkflow2010enterprisefeatures.wsp solution again, but
       this time select only the Central Admin web application as the "Deploy To" location.
       It is not necessary to retract the solution first, just deploy it again.
   1.3 The next step is to import the Nintex License.
       If you return to the Home page of Central Admin you will notice a new configuration
       section called "Nintex Workflow Management". 
      Click on 'Nintex Workflow Management' and select 'Licensing'


      From here you can click on the 'Import' button... to import your license file.


Ok, once this is all done we are ready to:
2- Configure the Nintex database.
In Central Admin go to the Nintex Workflow Management section.
Click on the "Database Setup" link and then click on the "Create" button.
Provide details of your database server and click on the "OK" button to allow the database to be generated.
The cool thing here is that in previous versions of Nintex Workflow (for SharePoint 2007) it was really tricky to get the database connection details working in a single server installation. It seems like it has all been taken care of since I am able to use my Windows Authentication to access the database without any problems.

Great, we are moving ahead... the next step is to:
3 - Configure the Nintex Workflow 2010 Server Settings
This will require that we:
    3.1 Perform Web Application Activation
    3.2 Enable Workflow Actions
    3.3 Configure Email Settings
    3.4 Enable and Configure Lazy Approval
   
    3.1 Perform Web Application Activation:
          In Central Admin go to the 'Nintex Workflow Management' section and click on
          "web application activation"
          Activate the feature to the applicable web application.
         
    3.2 Enable Workflow Actions
          In Central Admin go to the 'Nintex Workflow Management' section and click on

          "manage allowed actions"
          Select the workflow actions which you want to allow in your farm and click on OK.
         
    3.3 Configure Email Settings
          In Central Admin go to the 'Nintex Workflow Management' section and click on

          "Global settings"
          Provide the appropriate smtp server settings and click on "OK"

3.4 Enable and Configure Lazy Approval
         In Central Admin go to the 'Nintex Workflow Management' section and click on

         "LazyApproval Settings"
         Click on the "Enable / Disable LazyApproval" shortcut to enable LazyApproval.


The last step is to:
4 - Activate Features
Go to the Site Collection Features of your site on which you want to use Nintex Workflow 2010. (In SP2010 it is located under "Site Settings" --> Site Collection Features under Site Collection Administration)
You will see the following new site collection features.
Enable all of them:

Go to the Site Features of your site on which you want to use Nintex Workflow 2010. (In SP2010 it is located under "Site Settings" --> Manage site features under Site Actions)
Congratulations, Nintex Workflow 2010 have now been installed and configured and you can begin building workflow solutions !!!

In my next post I will show how to build a simple workflow to test whether the installation was successful.

Enjoy !!

You will see the following new site features.
Enable all of them:

4

Add code to an InfoPath 2010 Form

Today I started an investigation on the changes between InfoPath 2007 development and InfoPath 2010 development.

I really hope that InfoPath 2010 will bring more functionality and development flexibility as it really is a great "quick-win" tool for business which is sometimes crippled by a lack of development richness.

So.. one of my first questions was.. how easy is it to develop code behind (create custom code) for an InfoPath 2010 Form.

This tutorial will show you that it is still extremely easy to accomplish adding custom code, and my initial impression is that for a developer things will only become easier when moving to InfoPath 2010.

Prerequisites:

1.  Make sure you meet the minimum system requirements (available here).
2.  Install Visual Studio Tools for Applications (VSTA).
3.  Choose a programming language (inside the InfoPath Forms Designer).
4.  Add event handlers and code.

Let's get Started:
Open Microsoft InfoPath Designer 2010.
From the Form Templates Dialog, select "Blank Form".























Change the default Label on the form to something appropriate.
Since this is a first InfoPath 2010 tutorial, we cannot use anything else than "Hello World"
Click on the form and select the "Home" tab from the ribbon. Expand the controls pane to view the available controls.
Add a Button and a Text Box to your form under the "This is a 'Hellow World' label.

Your form will now look like this:












If you click on the 'Developer' tab in the ribbon, you will see you can se the programming language of the form.

When you click on the Language command you will see the 'Form Options' dialog with the 'Programming' section selected. In here click on 'Change Language' and specify the language of choice.

Once your development language has been specified you can go ahead to add custom code to your form.
In design mode, select the custom button on your form and you will notice the ribbon automatically changes to show 'Control Tools' pane.
Click on the Properties item and click on the 'Custom Code' command.

If your prerequisites were installed correctly, InfoPath forms designer will now open Visual Studio Tools for Applications and create a event handler for the button click event.
Inside the FormCode.cs you will see the following code:

public void CTRL1_5_Clicked(object sender, ClickedEventArgs e)

{
}

Add your custom code inside this event. I added some code to set the field value of the textbox (custom field) which I added earlier in this tutorial:

public void CTRL1_5_Clicked(object sender, ClickedEventArgs e)

{
    XPathNavigator domNav = MainDataSource.CreateNavigator();
    XPathNavigator field = domNav.SelectSingleNode("/my:myFields/my:field1", NamespaceManager);
    field.SetValue("Hello World");
}

Build your code and save the project.
Return to the InfoPath Forms Designer.
On the Home pane in the ribbon you will see on the far right the form preview command.
Click on this command to preview your form.

If you preview the form and click on the button you will see the custom code execute and add a value to the custom field which is then displayed in the textbox.
You can add breakpoints to your code to step through it if you want.

In the next post will I show how easy it is to publish the InfpPath form.

Enjoy !!