This documentation is archived and is not being maintained.

How to: Create a Custom Field Type and Field Control

Windows SharePoint Services 3

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

To create a custom field type, you can extend a default Windows SharePoint Services field type by defining a custom field type and control for displaying the field, and then adding a field type definition to register the field type and its control. You can create a Class Library project that defines custom classes for the field type and the control, copy the DLL of your project to the global assembly cache (GAC), and then add an XML file containing a definition that references the DLL to Local_Drive:\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML.

Most field types that are defined in the Microsoft.SharePoint namespace are associated with field controls that are defined in the Microsoft.SharePoint.WebControls namespace. For example, the SPFieldText class, which defines the field type for a single line of text, is associated with the Microsoft.SharePoint.WebControls.TextField class, which is specifically designed to display an SPFieldText object. A field type defines the metadata that is specific to a field instance. A field control defines the logic and behavior for displaying data according to the three control modes used in SharePoint lists: New, Display, and Edit. For more information about the object model for field types and field controls, see Custom Field Types.

You define a field type class and its control by creating an assembly. You register the class and its assembly, and also specify metadata and display patterns, through an XML file written in Collaborative Application Markup Language Core Schemas.

The following example defines a custom field for displaying company logos that derives from the SPFieldText class.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web.UI.WebControls;


namespace MS.Samples.SharePoint.CustomFieldType
{
    public class MyCompanyLogoField : SPFieldText
    {
        public MyCompanyLogoField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {}

        public MyCompanyLogoField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {}

        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl fieldControl = new CompanyLogoPickerFieldControl(this);

                fieldControl.FieldName = InternalName;

                return fieldControl;
            }
        }
    }
}

The example overrides the FieldRenderingControl property to call a custom CompanyLogoPickerFieldControl constructor that is defined in the next example.

The following example defines a custom control for displaying the previous custom field. The example overrides the CreateChildControls method to define a table for displaying a drop-down ListBox and corresponding images for selecting company logos.

The example specifies a default image file, MyDefaultLogo.png, to use for company logos, but this can be any name or image file type that you prefer.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace MS.Samples.SharePoint.CustomFieldType
{
    public class CompanyLogoPickerFieldControl : TextField
    {
        private MyCompanyLogoField field;
        private ListBox listBox;
        private HtmlTable table;

        public CompanyLogoPickerFieldControl(MyCompanyLogoField parentField)
        {
            this.field = parentField;
            this.listBox = new ListBox();
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            this.table = new HtmlTable();

            HtmlTableRow row = new HtmlTableRow();
            table.Rows.Add(row);

            HtmlTableCell cell = null;

            if (this.ControlMode == SPControlMode.Edit || this.ControlMode == SPControlMode.New)
            {
                cell = new HtmlTableCell();

                cell.ColSpan = 2;
                cell.Attributes["class"] = "ms-formdescription";
                cell.InnerText = "Choose a logo:";

                row = new HtmlTableRow();
                table.Rows.Add(row);

                cell = new HtmlTableCell();
                row.Cells.Add(cell);

                // Create a list selector.
                this.listBox = new ListBox();
                this.listBox.Rows = 12;

                SPSite site = SPContext.GetContext(this.Context).Site;

                SPDataSource dataSource = new SPDataSource();
                dataSource.List = site.RootWeb.Lists["Logos"];

                this.listBox.DataSource = dataSource;
                this.listBox.DataTextField = "Title";
                this.listBox.DataValueField = "Name";

                this.listBox.DataBind();

                // Get the current value of the field.
                String currentValue = (String)this.ItemFieldValue;

                if (currentValue != null && currentValue != String.Empty)
                {
                    this.listBox.SelectedValue = currentValue;
                }
                else if (this.listBox.Items.Count > 0)
                {
                    this.listBox.SelectedIndex = 0;
                }

                // Add the script which updates the preview image.
                this.listBox.Attributes["onchange"] = "document.all.imgLogoPreview.src = '/logos/' + this.options[this.selectedIndex].value;";
                cell.Controls.Add(this.listBox);
                row.Cells.Add(cell);
            }

            cell = new HtmlTableCell();

            LiteralControl literalControl = new LiteralControl();

            String logo = null;
            object logoObject = this.ItemFieldValue;

            if (logoObject != null)
            {
                logo = (String)logoObject;
            }

            if (logo == null || logo == String.Empty)
            {
                logo = "MyDefaultLogo.png";
            }

            literalControl.Text = "<img id='imgLogoPreview' src='/logos/" + logo + "'></img>";

            cell.Controls.Add(literalControl);

            row.Cells.Add(cell);

            base.Controls.Add(table);
        }

        public override void UpdateFieldValueInItem()
        {
            this.EnsureChildControls();

            try
            {
                this.Value = this.listBox.SelectedValue;
                this.ItemFieldValue = this.Value;
            }
            catch (Exception)
            {
                ;
            }
        }

        protected override void Render(HtmlTextWriter output)
        {
            this.table.RenderControl(output);
        }
    }
}

To create a custom field type and a custom field control

  1. In Microsoft Visual Studio, click File, point to New, and then click Project.

  2. In the New Project dialog box, select the language for your project in the Project Types box, select Class Library in the Templates box, type a name and location for building the project, and then click OK.

  3. To add a reference to the Microsoft.SharePoint assembly, right-click the project in Solution Explorer, and on the .NET tab in the Add Reference dialog box, select Windows SharePoint Services, and then click OK.

  4. To give your custom assembly a strong name when you build the project, right-click Properties in Solution Explorer, click Signing, select Sign the assembly, and specify a name for the strong name key file.

  5. Double-click the default project .cs or .vb file in Solution Explorer, and add code such as in the first example to define a class for a custom field that extends a default Windows SharePoint Services field type.

  6. Right-click the project in Solution Explorer, point to Add, and then click New Item.

  7. Select Code File in the Add New Item dialog box, and then click Add.

  8. In Solution Explorer double-click the new .cs or .vb file that you created in the previous step, and add code such as in the second example to define a control for displaying the custom field that extends a default Windows SharePoint Services field control.

  9. Press CTRL+SHIFT+B to build the solution.

  10. In Windows Explorer, drag the DLL from your project folder into the GAC.

The following example registers the custom field type that is defined in the previous example.

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
  <FieldType>
    <Field Name="TypeName">MyCompanyLogoField</Field>
    <Field Name="ParentType">Text</Field>
    <Field Name="TypeDisplayName">My Company Logo</Field>
    <Field Name="TypeShortDescription">My Company Logo</Field>
    <Field Name="UserCreatable">TRUE</Field>
    <Field Name="Sortable">TRUE</Field>
    <Field Name="AllowBaseTypeRendering">TRUE</Field>
    <Field Name="Filterable">TRUE</Field>
    <Field Name="FieldTypeClass">MS.Samples.SharePoint.CustomFieldType.MyCompanyLogoField, MyExtendedFieldTypeControl1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34b96198b6e14eee</Field>
    <PropertySchema>
      <Fields></Fields>
    </PropertySchema>
    <RenderPattern Name="DisplayPattern">
      <HTML><![CDATA[<img style="zoom: 50%" src="/logos/]]></HTML>
      <Column HTMLEncode="TRUE" />
      <HTML><![CDATA[">]]></HTML>
    </RenderPattern>
  </FieldType>
</FieldTypes>

The RenderPattern Element (Field Types) element defines how to display the field in the All Items list view.

This file must be named in the format fldtypes*.xml (for example, fldtypes_customfield.xml) and placed in Local_Drive:\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML so that Windows SharePoint Services merges the contents of your custom file with the default FLDTYPES.XML file.

For more information about the schema for a custom field type, see Custom Field Type Definition.

To register and test the example

  1. In a text editor, create a CAML field type definition file in \TEMPLATE\XML that specifies the custom field type and control that you created in the previous procedure.

  2. Add the CAML file to Local_Drive:\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML.

  3. At a command prompt, type iisreset to reset Internet Information Services (IIS).

  4. In the root Web site of a site collection, create a picture library named "logos" to contain the image files to use for company logos.

  5. In a view of the list to which you want to add the custom field type, click Settings, and then click Create Column.

  6. On the Create Column page, add the field type to the view, which in the previous example is called My Company Logo.

  7. Edit existing items or create items in the list to specify company logos, which are displayed in all three control modes and in the list view.

Show: