<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

How to create and deploy a custom field type within Sharepoint

Published on
18,306 Points
12,206 Views
1 Endorsement
Last Modified:
Approved
Community Pick
This example will use a custom field type to create a drop down list populated from a Sharepoint List.

There are four main components to building a custom field&

"      Field Class* This must inherit from an existing SPField class. e.g. SPFieldText. It handles custom validation for the field, as well as defining the Field Control used to display it.
"      User Control Rendering Template.  This defines the control to be used to display the custom field.
"      Field Control Class. This contains the code-behind for the user control file, and defines how the control is rendered.
"      Field Type Definition File. This contains the information that SharePoint needs to correctly render the field, as well as information about the assembly that contains the compiled field type.

The example demonstrates a custom field type designed to list all entries within an example list entitled Organisation List.
 

1. Field Class



Each instance of this class represents a separate field based on the custom field type. It must inherit from one of the SPField subtypes, a list of which can be found at the end of this document. The most commonly used subtype is SPFieldText, and this is used in the following example code.

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;

namespace Company.Application.Controls
{
    [CLSCompliant(false)]
    [Guid("01d5cd28-741b-4229-8d47-24e5a068b5af")]
    public class OrganisationDropDownField : SPFieldText
    {
        public OrganisationDropDownField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
        }
        
        public OrganisationDropDownField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
        }

        public override BaseFieldControl FieldRenderingControl
        {
            [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
            get
            {
                BaseFieldControl fieldControl = new OrganisationDropDownFieldControl();
                fieldControl.FieldName = this.InternalName;

                return fieldControl;
            }
        }

        public override string GetValidatedString(object value)
        {
            if (Required && String.IsNullOrEmpty(value.ToString()))
            {
                throw new SPFieldValidationException("No Organisation selected");
            }
            return base.GetValidatedString(value);
        }
    }
}

Open in new window



Here the BaseFieldControl is set to use a custom drop down control called OrganisationDropDownFieldControl, defined in the Field Control Class below. In the example some custom validation is also included within the overridden GetValidatedString method, to ensure a value is selected when mandatory.

2. User Control Rendering Template



In order to render the drop down control, a user control is required, consisting of an XML rendering template and a code behind file.

The rendering templated is defined within an .ascx file, and in the example is little more than an asp dropdownlist control, as follows:

<%@ Control Language="C#" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls" %>

<SharePoint:RenderingTemplate ID="OrganisationDropDownFieldControl" runat="server">
  <Template>
    <asp:DropDownList ID="OrganisationSelector" runat="server" />
  </Template>
</SharePoint:RenderingTemplate> 

Open in new window


The ID of the rendering template element matches the name of the code behind class for this user control, while the ID of the drop down list matches the name of the DropDownList property within the control class.

3. Field Control Class



The field control class is the code behind file for the rendering template, and is compiled alongside the Field Class in the same assembly. It is this class that is used to populate the drop down list with its data, as well as handling the current value.

using System;
using System.Runtime.InteropServices;
using System.Web.UI.WebControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace Company.Application.Controls
{
    [CLSCompliant(false)]
    [Guid("dfbce0dc-3215-4352-b65f-25a83e8b427b")]
    public class OrganisationDropDownFieldControl : BaseFieldControl
    {
        protected DropDownList OrganisationSelector;

        protected override string DefaultTemplateName
        {
            get
            {
                return "OrganisationDropDownFieldControl";
            }
        }

        public override object Value
        {
            get
            {
                EnsureChildControls();
                return OrganisationSelector.SelectedValue;
            }
            set
            {
                EnsureChildControls();
                OrganisationSelector.SelectedValue = (string)this.ItemFieldValue;
            }
        }

        protected override void CreateChildControls()
        {
            if (Field == null || ControlMode == SPControlMode.Display)
                return;

            base.CreateChildControls();

            OrganisationSelector = (DropDownList)TemplateContainer.FindControl("OrganisationSelector");

            if (OrganisationSelector == null)
            {
                throw new ApplicationException("Error: Cannot load .ascx file");
            }

            if (OrganisationSelector.Items.Count == 0)
            {
                if (SPContext.Current.Site != null)
                {
                    SPList orgList = SPContext.Current.Site.RootWeb.Lists["Organisations List"];
                    if (orgList == null)
                    {
                        throw new ApplicationException("Organisations List not found");
                    }

                    OrganisationSelector.Items.Add(String.Empty);
                    foreach (SPItem org in orgList.Items)
                    {
                        if (org["Title"] == null)
                        {
                            continue;
                        }
                        string orgTitle = org["Title"].ToString();
                        OrganisationSelector.Items.Add(new ListItem(orgTitle, orgTitle));
                    }
                }
            }
        }
    }
}

Open in new window


The class must inherit from BaseFieldControl (or one of the classes in Windows SharePoint Services that derive from it), and be modified as follows:

"      Include a .Net control within its properties of the desired type, with a name matching the ID of the corresponding control within the template. The example field includes a DropDownList control called OrganisationSelector.
"      Override the DefaultTemplateName property with the name of rendering template
"      Override the value property to enable the getting and setting of the current value of the control.
"      Override the CreateChildControls method to populate the control. For the example control, this is where the drop down list is populated with values from the Organisations List.

This class must be compiled into the same assembly as the Field Class.
 

4. Field Type Definition File



The final requirement for the custom control is a field type definition file, which holds the metadata behind the field itself.

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
  <FieldType>
    <Field Name="TypeName">OrganisationDropDownField</Field>
    <Field Name="ParentType">Text</Field>
    <Field Name="TypeDisplayName">Organisation</Field>
    <Field Name="TypeShortDescription">Organisation</Field>
    <Field Name="UserCreatable">TRUE</Field>
    <Field Name="ShowInListCreate">TRUE</Field>
    <Field Name="ShowInSurveyCreate">TRUE</Field>
    <Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
    <Field Name="ShowInColumnTemplateCreate">TRUE</Field>
    <Field Name="SQLType">ntext</Field>
    <Field Name="FieldTypeClass">Company.Application.Controls.OrganisationDropDownField, Company.Application.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7389d5f4596c3c69 </Field>
    <RenderPattern Name="DisplayPattern">
      <Switch>
        <Expr>
          <Column/>
        </Expr>
        <Case Value="">
        </Case>
        <Default>
        </Default>
      </Switch>
    </RenderPattern>
  </FieldType>
</FieldTypes>

Open in new window



The TypeName element must match the name of the field control, while ParentType must match the SPField subtype used within the Field Class. Note the FieldTypeClass element that must match the name of the Field Class itself, along with its assembly details.
 

5. Deploying the custom field types



The Field Class and Field Control Class must be compiled into a signed assembly, which must be placed in the GAC ( a custom field binary cannot be installed into the Application bin directory).
In order to have the relevant files deployed automatically by the solution, the rendering template and field type definition file must be added to the VS project using the same folder path as will be used by SharePoint.
Therefore, add a new folder under the VS project with a name of 12. Below that, add another folder called Template and within that add two more folders: ControlTemplates and XML. Place the rendering template in the ControlTemplates folder, and add the field type definition file to the XML folder.
Next add a manifest.xml file that will tell sharepoint where to deploy the individual components, as follows:

<Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="F3A12E2E-31EF-478d-AC2A-E389704F281E">
  <Assemblies>
    <Assembly Location="Company.Application.Controls.dll" DeploymentTarget="GlobalAssemblyCache">
    </Assembly>
  </Assemblies>
  <TemplateFiles>
    <TemplateFile Location="XML\fldtypes_OrganisationField.xml" />
    <TemplateFile Location="ControlTemplates\OrganisationFieldControl.ascx" />
  </TemplateFiles>
</Solution>

Open in new window


Note the Assembly element that holds the name of the dll, with a DeploymentTarget of the GAC. The Template files entry will place the rendering template and field definition files in their relevant locations within the sharepoint hierarchy
Because the assembly has been placed in the GAC, it will need to be manually added to the SafeControls section of each application using the control.
<SafeControl Assembly="Company.Application.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7389d5f4596c3c69", Namespace="Company.Application.Controls" TypeName="*" Safe="True" />

Open in new window




 
Finally add a definition file to automatically include all relevant files into a .wsp SharePoint solution package.

;WSP CAB Generation
.Set DiskDirectoryTemplate=CDROM
.Set CompressionType=MSZIP
.Set UniqueFiles=Off
.Set Cabinet=On

Manifest.xml
%assembly%

.Set DestinationDir="XML"
12\Template\XML\fldtypes_OrganisationField.xml

.Set DestinationDir="ControlTemplates"
12\Template\ControlTemplates\OrganisationFieldControl.ascx

Open in new window


This package can then be deployed using the STSADM utility.
SPField subtypes

"      Microsoft.SharePoint.SPFieldAttachments    
"      Microsoft.SharePoint.SPFieldBoolean    
"      Microsoft.SharePoint.SPFieldCalculated    
"      Microsoft.SharePoint.SPFieldComputed    
"      Microsoft.SharePoint.SPFieldCrossProjectLink    
"      Microsoft.SharePoint.SPFieldDateTime    
"      Microsoft.SharePoint.SPFieldFile    
"      Microsoft.SharePoint.SPFieldLookup    
"      Microsoft.SharePoint.SPFieldMultiChoice    
"      Microsoft.SharePoint.SPFieldMultiColumn    
"      Microsoft.SharePoint.SPFieldMultiLineText    
"      Microsoft.SharePoint.SPFieldNumber    
"      Microsoft.SharePoint.SPFieldPageSeparator    
"      Microsoft.SharePoint.SPFieldRecurrence    
"      Microsoft.SharePoint.SPFieldText    
"      Microsoft.SharePoint.SPFieldUrl

1
Comment
1 Comment

Featured Post

IT Pros Agree: AI and Machine Learning Key

We’d all like to think our company’s data is well protected, but when you ask IT professionals they admit the data probably is not as safe as it could be.

Join & Write a Comment

Basic Overview of office 365 user portal
Watch this simple and effective video tutorial to extract attachments from Outlook 2007 and try this easy method by yourself. No need to go anywhere, just watch the video and export attachments from Outlook in few simple steps. To know more, click h…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month