Inheriting from BaseFieldControl
The
SPField class has many properties that define how a column based on the
field type will behave. One of these properties, FieldRenderingControl
leads us onto the BaseFieldControl class.
Each SPField-derived class must implement the
FieldRenderingControl property, which will return an object of type
BaseFieldControl. Notice, however, that BaseFieldControl is an abstract
class. This means that in practice, each SPField derived class must
return a concrete implementation of the BaseFieldControl. Some examples
of these implementations include LookupField and FileField. These
FieldRenderingControls are responsible for defining and implementing
the user interface for each field type. For example, in the case of the
LookupField control, when the page is in edit mode, the user interface
may consist of a drop down control containing values from the
configured lookup list. In the same way as the SPField object
represents the lowest level of data access code, the BaseFieldControl
represents the lowest level of user interface code that can be written
against the SharePoint platform.
Continuing with our earlier SPField example, we’ll
add a custom field control to provide us with a user interface for
capturing data.
Add a new class file named AddressField.cs. Insert the following code:
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;
namespace CustomField
{
class AddressField : BaseFieldControl
{
private TextBox _address;
private TextBox _apartmentNumber;
private TextBox _city;
private TextBox _state;
private TextBox _zip;
protected override void CreateChildControls()
{
if (this.Field == null || this.ControlMode == SPControlMode.Display
|| this.ControlMode == SPControlMode.Invalid)
{
return;
}
else
{
base.CreateChildControls();
_address = new TextBox();
_apartmentNumber = new TextBox();
_city = new TextBox();
_state = new TextBox();
_zip = new TextBox();
Table tab = new Table();
tab.Controls.Add(BuildRow("Street Address", _address));
tab.Controls.Add(BuildRow("Apartment Number", _apartmentNumber));
tab.Controls.Add(BuildRow("City", _city));
tab.Controls.Add(BuildRow("State", _state));
tab.Controls.Add(BuildRow("ZIP Code", _zip));
this.Controls.Add(tab);
}
}
private TableRow BuildRow(string labelText, WebControl valueControl)
{
TableRow row = new TableRow();
TableCell label = new TableCell();
TableCell value = new TableCell();
label.Text = labelText;
value.Controls.Add(valueControl);
row.Controls.Add(label);
row.Controls.Add(value);
return row;
}
public override object Value
{
get
{
EnsureChildControls();
SPAddressValue field = new SPAddressValue();
field.StreetAddress = _address.Text;
field.ApartmentNumber = _apartmentNumber.Text;
field.City = _city.Text;
field.State = _state.Text;
field.Zip = _zip.Text;
return field;
}
set
{
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
SPAddressValue field = new SPAddressValue(value.ToString());
_address.Text = field.StreetAddress;
_apartmentNumber.Text = field.ApartmentNumber;
_city.Text = field.City;
_state.Text = field.State;
_zip.Text = field.Zip;
}
}
}
}
}
To hook up our custom BaseFieldControl to our SPField implementation, add the following code to the SPFieldAddress.cs class:
public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl control = new AddressField();
control.FieldName = this.InternalName;
return control;
}
}
2. Validation
In
SharePoint 2007, adding validation to fields was one of the main
reasons for creating a custom field control. As you’ve seen, creating
field controls is a time-consuming task. The good people at Microsoft
realized that, from a development perspective, this wasn’t a good use
of resources and as a result, in SharePoint 2010, column validation has
been added to the SPField class. In effect, column validation
eliminates the need for a lot of custom field development by making it
possible to enter validation formulae via the user interface.
When you’re adding a new column, you’ll see a new
Column Validation section at the bottom of the page, as shown next.
Validation formulae use the same syntax as calculated columns and as
such can include pretty complex logic.
One thing that isn’t apparent from the user
interface is that behind the scenes, SharePoint creates a JavaScript
representation of the validation formula. This allows for values to be
validated in the user interface without the need for a post back.
The values for these properties are stored in the
ValidationEcmaScript, ValidationFormula, and ValidationMessage
properties of the SPField object.