Building Block: Columns and Field Types
Last modified: July 08, 2010
Applies to: SharePoint Foundation 2010
This topic provides a brief overview of Columns and Field Types as development building blocks in Microsoft SharePoint Foundation.
The term ‘field’ has two closely related meanings in SharePoint Foundation development. Sometimes it refers to a column in a list, but when a single list item is under discussion, the term ‘field’ has a meaning similar to the meaning of ‘cell’ where cell is the intersection of a column and a row of a table. Partly for this reason, the terms ‘column’ and ‘field’ are virtual synonyms in the context of SharePoint Foundation development. For example, an object that represents a column is an object of the SPField class or a class that is derived from it.
In SharePoint Foundation, columns not only contain data of a particular data type, they are themselves a kind of type because the same column can be used on multiple lists with different data. A column can persist in a site column gallery. A site column from the gallery can be added to any list in the site, either programmatically or through the user interface (UI). A column can also be added to a content type, either programmatically or through the UI such as by a content type designer.
Some of the site columns that are built into SharePoint Foundation include Address, Birthday, Assistant’s Name, and URL. Each column belongs to one or another of a small set of kinds of types, sometimes called ‘type kinds’, but more often called ‘field types’. For example, the field types of Address, Birthday, Assistant’s Name, and URL are, respectively, Multiline Text, Date and Time, Single line of text, and Hyperlink. The complete list of field types is specified by the values of the SPFieldType enumeration. Some of the most important values include:
Boolean – A field that accepts only true or false as values.
Calculated – A field whose value is calculated at runtime from a mathematical formula.
Choice – A field that can have only one value and the value must be included in a finite enumerated list of values. There is also a Multichoice field type that allows more than one value from the list.
Computed – A field whose value depends on the value of another field in the same list item. It is usually the value of a logical operation performed on one or more other fields.
Lookup – A field that is similar to a Choice field, but the list of possible values comes from a column on some other list.
Text – A field that accepts a single line of text. There is also a Multiline Text field type.
Here are some of the most interesting operations that you can perform with fields, either programmatically or with XML markup:
Read and write the value of a particular field in a particular list item.
Add and delete columns from lists.
Add and delete columns from site column galleries.
Change the way that fields render on New list item, Edit list item, and Display list item forms.
Change the way that columns render on list views.
Create a custom field type.
Create one or more custom rendering controls to render the field of various types of pages and forms.
Create one or more mobile rendering controls to render the field on mobile devices.
Exclude unwanted columns from query results.
Perform a join of two tables in a query when one table has a Lookup column that looks up to the other table.
This topic refers explicitly only to classes in the SharePoint Foundation server object model. The client object model has parallel classes for most of these server classes. As a general, but not universal, rule when the server class name begins with "SP", the parallel object class has the same name but without the "SP" prefix.
One of the most common coding tasks in SharePoint Foundation development is reading and writing to a field in a list item. To do this, get a reference to the SPListItem object that represents the list item and then use one of its indexers (Item) to reference a particular field. There is an indexer that accepts an Int32 object, another indexer that accepts a String object, and a third indexer that takes a Guid object. The last one can be used to get the field by its Id property. You can pass either the field’s internal name or its display name with the String indexer.
SPField and Its Derivatives
Each field type is represented by a class that derives from SPField. For example, SPFieldBoolean represents Boolean fields and SPFieldChoice represents Choice fields. Any specified column in a Web site’s site column gallery is an object of one of these classes. The properties of the class differentiate the various columns of a specified field type. For example, the Birthday column and the Due Date column are both objects of the SPFieldDateTime class, but they differ in the value of the Title property among others. Among the members of the SPField class is a ListsFieldUsedIn() property that reports which lists include the column. And it has an EnforceUniqueValues method which ensures that no two cells in the column have the same value, as well as Filterable and Sortable properties.
There are some members of each SPField-derived class that may suggest that their objects represent a particular field in a list item; that is, an entity that would, in a list view, correspond to a particular cell in the column. For example, there is a GetFieldValue(String) method and a HasValue(Object) method. There is also a FieldRenderingControl property that determines how the field is rendered when a single list item is rendered on a form, such as a New or Edit form. While it may be helpful to think of an SPField-derived object in this way when you are working with these members, keep in mind that the object does not have any property that holds the value of a field in a particular list item, and calling the SPField.Update() method does not save changes made to such a value. (The object in the FieldRenderingControl property does have such a member; specifically, the ItemFieldValue property.) Similarly, the GetFieldValue(String) does not really get a value; it converts a value that is passed to it as a parameter. And the HasValue(Object) simply reports whether an object passed to it is null. Of course, the intention is that the value passed to either method is the value of the field in a particular list item; but it is the responsibility of the programmer to use the methods in this way. The primary way to read and write the data of a particular field in a particular list item is to use an indexer with an SPListItem object.
BaseFieldControl and its Derivatives
The rendering of a field in a particular list item on the New item and Edit item forms (and sometimes the Display form), is usually managed by an object of a class derived from BaseFieldControl. For example, an SPFieldBoolean object is rendered by an object of the BooleanField class and the SPFieldUrl object is rendered by an object of the UrlField class.
An object that is instantiating a rendering control holds, in its Field property, a reference to the field object that it renders. The latter holds a reference to its rendering control in its FieldRenderingControl property. As these reciprocal references suggest, the two objects are partners. The SPField-derived object handles column configuration, while the BaseFieldControl-derived rendering control handles interaction with users and the rendering of the fields of list items in the UI.
A rendering control object is kept in sync with the field in the content database by the Value and ItemFieldValue properties, the UpdateFieldValueInItem() method, and the OnLoad(EventArgs) handler. On the Edit form, the ItemFieldValue property has the value, in the content database, of the field in the particular list item that is being rendered in the form. On the New form, ItemFieldValue has a default value. The OnLoad(EventArgs) handler assigns to the Value property the value of the ItemFieldValue property. If a user sets or changes the value on the form, the UpdateFieldValueInItem() method assigns to the ItemFieldValue property the value of the Value property.
You can create a custom field rendering control by deriving a new class from BaseFieldControl class or from a class that inherits from it. For more information, see How to: Create a Field Rendering Control.
Most of the work of creating and compositing a field rendering control, including the creation of its child controls, is done by a rendering template. Every rendering control has at least one rendering template associated with it. A RenderingTemplate object is defined as a RenderingTemplate element in an ascx file in the folder %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\CONTROLTEMPLATES. The rendering template is referenced by its ID value in the rendering control object's TemplateName property. Since the rendering template is doing most of the rendering work, the CreateChildControls() method has much less to do than it would in a classic Microsoft ASP.NET control class. Typically, it provides only a final polish to the child controls. For example, it might assign a default value to a child control if the field is being rendered on the New item form, or assign the field's current value to a child control on the Edit item form.
You can create custom rendering templates to use with your custom rendering controls. For more information, see How to: Create Field Rendering Templates.
SPMobileBaseFieldControl and Its Derivatives
Field rendering on the mobile device versions of SharePoint Foundation pages is managed by classes that derive from SPMobileBaseFieldControl. For example, an SPFieldBoolean object is rendered by an object of the SPMobileBooleanField class. You can create your own mobile field rendering controls that derive from one of these classes.
In a broad sense, these classes provide the same functionality for mobile forms as the BaseFieldControl-derived classes provide for nonmobile forms. However, there are some differences in the architecture:
The inheritance tree of the SPMobileBaseFieldControl-derived classes traces back to the Control class of ASP.NET, rather than the Control class. Moreover, within the SharePoint Foundation part of the tree, the functions that are inherited from the TemplateBasedControl and FormComponent classes in nonmobile rendering controls are combined in the SPMobileComponent class for mobile rendering controls.
The mobile rendering controls have their own set of rendering templates and if you created a custom rendering template for use on non-mobile pages, you would probably need to create a different one for use on a mobile page.
Custom field rendering controls that you create for mobile contexts rely more on the CreateChildControls() method of the control to render a field, and correspondingly less on the rendering template, than is the case for custom field rendering controls that you create for nonmobile contexts. Moreover, when creating custom mobile rendering controls, you will not often override the CreateChildControls() method itself. Instead, you will typically override one or more of four other methods that are called by CreateChildControls(): CreateControlForDisplay(), CreateControlForEdit(), CreateControlForNew(), and CreateControlForView().
An object that is instantiating a mobile rendering control holds, in its Field property, a reference to the field object that it renders. The latter holds a reference to its mobile rendering control in its FieldRenderingMobileControl property. The members involved in keeping the content database and the rendering control synchronized are slightly different in the case of SPMobileBaseFieldControl-derived classes from what they are in BaseFieldControl-derived classes as described above.
For more information about field rendering on mobile pages, see How to: Customize Field Rendering on Mobile Pages.
Custom Field Value Classes
If you create a custom field type that holds a complex kind of data, you may need to create a custom field value class. Some of the built-in field types require special complex value types. For example, objects of the SPFieldLookup field type take values of a special type that is represented by the SPFieldLookupValue class. For more information about creating custom field value classes, see How to: Create a Custom Field Value Class.
ViewFieldsOnly and Joins
When you use an SPQuery object to represent a Collaborative Application Markup Language (CAML) query, you can use the ViewFields and ViewFieldsOnly properties to ensure that your query does not have to fetch unneeded fields from the content database. If you are using the LINQ to SharePoint provider to query list data, the LINQ select keyword can be used for the same purpose. There is also a Joins property that enables your query to join two or more lists. Alternatively, the LINQ to SharePoint provider supports the join keyword. For more information, see List Joins and Projections.
There is a substantial amount of XML markup involved in the definition of columns and field types.
Field Type Definitions
The detailed definition of a field type is provided by the Field element that is part of the main List schema. For more information, see Field Element (List). When a field is being deployed as part of a Feature, this same element is used in the manifest file for the Feature. For more information, see Field Definitions.
Field Type XML and XSLT Stylesheets
To be rendered fields must also be registered with SharePoint Foundation in files named on the pattern fldtypes*.xml located in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\XML. The format of the file is Field Type XML. This markup in these registrations is a simpler kind of field type definition. It reports certain basic characteristics of a field type and identifies the assembly and managed class of the field type. (Read-only access to a field type definition is available in the object model through the SPFieldTypeDefinition class.)
On list views, field values are rendered by an XSLT styleheet. The headers at the top of each column are also rendered by an XSLT stylesheet. You can create XSLT stylesheets for custom fields or to override the standard rendering of existing fields. All the stylesheets are persisted in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL.
ASP.NET User Controls
ASP.NET user controls, which are defined in ascx files, can be used for two purposes in field type development. First, field rendering on the Display, New and Edit forms that is done with a user control called a rendering controls (see BaseFieldControl and its Derivatives above) and a rendering template. A rendering template is defined with <RenderingTemplate> element in an ascx file in the folder %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates. It is represented in the object model by the RenderingTemplate class. This class provides you with an easy-to-use layer of abstraction on top of the ASP.NET system of templated user controls. For more information about rendering templates and their relation to rendering controls, see Rendering Templates. Second, when a field type itself has variable properities which have different values on the different lists that include the field, you reate a property editing control as a user control in an ascx file. For more information about this task, see Custom Field Type Property Rendering.
Join Types in the Query Schema
The Collaborative Application Markup Language (CAML) Query Schema includes a Join Element (View) that enables you to join to lists in a CAML query provided that one list has a Lookup column that looks up to a column in the other. This element also makes it possible to use implicit and explicit joins in a LINQ query that uses the LINQ to SharePoint provider.
Extensive and detailed information about using columns and field types in your development projects is located in the SharePoint Foundation 2010 Development in Depth section in the nodes for List Forms, Columns, and Custom Field Types. For information about development of mobile device rendering field rendering, see How to: Customize Field Rendering on Mobile Pages.
For detailed information about querying data in SharePoint Foundation, see Queries and Data Retrieval in SharePoint Foundation.