Patterns of Custom Field Rendering
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.
You have a wide variety of options for fine-grained control of how your custom fields are rendered. This topic discusses some common patterns and indicates how you can modify them to meet your needs.
This topic is about rendering custom fields and their values. It is not about rendering the variable properties of custom field types on the New Site Column, Change Site Column, Create Column, and Change Column pages. For information about rendering the variable field properties of custom field types, see Custom Field Type Property Rendering.
The simplest way to render a custom field type does not use field rendering controls or field rendering templates (see below). Instead, field rendering in all control modes (New, Edit, and Display) as well as on list views is done entirely by means of RenderPatterns defined in a field definition. But this method limits your validation logic to what can be accomplished in scripts. For that reason, you will probably find that you can use RenderPatterns only for rendering on list views and in Display mode, where validation is not an issue.
Every field rendering control has at least one field rendering template associated with it. The association is made by having the field rendering control hold in one of its properties a reference to the ID of the field rendering template. At render-time, Windows SharePoint Services 3.0 looks up the needed template by searching the IDs of all the render templates declared in .ascx files in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES (all of which load when the Web application starts). The rendering control's CreateChildControls method often does a final polish of the field's rendering, but most of the rendering work is done by the template.
The pattern of field rendering configuration that you will find yourself using most often as you develop custom field types has these characteristics:
There is a rendering control and it is associated with only one rendering template. The control uses its TemplateName property to specify template's ID.
This one template is used to provide most of the rendering of the field in the New and Edit modes.
The rendering control's CreateChildControls method assigns default values to the rendering control's child controls in New mode. It assigns the field's current values to the child controls in Edit mode. (It does nothing in Display mode.) It might also do other "final polish" rendering work such as assigning a CSS class to a child Label control.
Validation logic is implemented by the field rendering control's Validate, IsValid, and ErrorMessage members, and by the underlying field type's GetValidatedString method. (Validate might be called by CreateChildControls.)
This section discusses some of the ways that you can deviate from the standard pattern when your custom field type requires it.
Using a Template in Display Mode
There may be times when it is preferable to use a field rendering template, rather than a RenderPattern, even for Display mode. For example, you might have many custom field types that are virtually identical in their Display mode appearance. A RenderPattern is difficult to reuse across many field types, except by copying and pasting from one fldtypes*.xml to another (or within one such file). But if you've used this method, and if you need to make a change to the RenderPattern, you have to find all the places where you copied it. For this reason, you might prefer to use a field rendering template that can be referenced by many different rendering controls.
It is not likely that the same template can be used for all three control modes. The New and Edit modes require interactive controls such as editable text boxes, check boxes, radio buttons, and drop-down list controls. But the Display mode normally requires only Label or Literal controls or other static display controls. For this reason, you will probably need to create a different rendering template for Display mode. You specify this template (by ID) in the DisplayTemplateName property.
The rendering template that is actually used to render the field in any given context is the one returned by the rendering control's ControlTemplate property. Its get accessor selects from among the rendering templates associated with the rendering control, using decision criteria such as:
The current HTTP context
The control mode
Whether or not the field is required
Whether or not the field, if numerical, should be rendered as a percentage
Whether or not the list item is a folder
You can override this property and have its get accessor check the control mode and return DisplayTemplate when the mode is Display. (Unless it has been explicitly set to some other template, DisplayTemplate returns the template identified by DisplayTemplateName.) Unless you need other decision logic in the get accessor for ControlTemplate, you can simply have it call the base property's get accessor in New or Edit mode.
An alternate means of designating a rendering template in Display mode is to have the CreateChildControls method assign DisplayTemplateName to TemplateName in Display mode. (Unless it has been overridden, ControlTemplate returns Template and unless the latter's get accessor has been overridden, it returns the template identified by TemplateName.) A possible weakness of this approach is that the code does not run in a context in which the field is not being rendered, such as when, for debugging purposes, you are checking the value of ControlTemplate in the object model.
Other Situations Requiring Multiple Rendering Templates
Use an alternate template to render your custom field in any page context in which the main template does not meet your requirements. Some examples are listed here:
If the field is required on some lists but not on others, you can have an alternate template that is just like the main one except that it adds an indicator, say, a red asterisk, that the field is required on specific lists. Then have the get accessor of ControlTemplate check the Required property of the underlying field and return either Template or AlternateTemplate as appropriate.
If you plan to use many custom field types that will render almost identically, you may be able to achieve better code reuse by creating separate templates for use in New and Edit modes. The former would assign default values to child objects and the latter would assign current values. This would enable you to avoid repeating the assignment logic in the CreateChildControls method of every one of the custom field type classes. Again, the get accessor of ControlTemplate would determine which template is used based on the control mode.
Using an alternate template can also be useful when your field needs special rendering on certain Web sites, site collections, or Web applications. Consider, for example, a Web site designed for people with a visual impairment, such as color blindness. The get accessor of ControlTemplate can examine the value of RenderContext to see if the special template is needed and return the appropriate template.
For custom field types that inherit from SPFieldNumber and that sometimes, but not always, need to be rendered as percentages, having two different rendering templates can be a great development time saver. Override the get accessor of ControlTemplate to respond to the value of the SPFieldNumber.ShowAsPercentage property.
Adding More Template Associations
You can, of course, add more rendering template associations to the field rendering control that you derive from BaseFieldControl. We recommend that you follow this pattern:
Create a new private field named of type ITemplate.
Create new public property as a wrapper around the private field and give it a name such as circumstanceTemplate, where circumstance identifies the circumstance in which you anticipate using the template.
Create a second public property that returns a String and name it circumstanceTemplateName.
The get accessor for circumstanceTemplate should return the private field only if the latter is not null. Otherwise, it should return the ITemplate that is named by circumstanceTemplateName. Use the GetTemplateByName method to do this.
Override the get accessor of ControlTemplate to return circumstanceTemplate whenever circumstance is true.
Using Web Custom Controls as Templates
Your custom field rendering control will also inherit two special ITemplate properties:
CustomTemplate and CustomAlternateTemplate. These two properties are marked with the [PersistenceMode(PersistenceMode.InnerProperty)] attribute. This means that the ITemplate objects that they return are compiled and they persist inside the field rendering control as nested tags. There are several advantages to using precompiled templates; for example, they can be added to a page in a visual designer such as Microsoft Office SharePoint Designer 2007 or Microsoft Visual Studio 2005 by dragging and dropping them from the designer toolbox. But there are disadvantages as well. For more information about Web user controls and custom Web controls, see Web User Controls and Web Custom Controls and PersistenceModeAttribute.
In Windows SharePoint Services 3.0, field rendering with custom field rendering controls for mobile devices is similar to field rendering with custom field rendering controls for computers. But keep these differences in mind:
Mobile pages are an entirely different set of pages from the regular pages and they reference a different set of RenderingTemplates.
Mobile RenderingTemplates are declared in MobileDefaultTemplates.ascx, not DefaultTemplates.ascx.
Mobile field rendering controls have their own namespace, Microsoft.SharePoint.MobileControls (rather than Microsoft.SharePoint.WebControls) and they derive from classes in ASP.NET's System.Web.UI.MobileControls, rather than System.Web.UI.WebControls.
The inheritance hierarchy for mobile field rendering controls is a little different from that of regular field rendering controls. For example, the functions of the TemplateBasedControl and FormComponent in regular field rendering are combined in the SPMobileComponent class.
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 computer browsers. Moreover, for 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. For more information about mobile page rendering and custom field rendering controls, see Mobile Page Rendering System and Walkthrough: Creating a Custom Field Rendering Control for Mobile Pages.