SCKattered Thoughts
Dec 22

By: lnorton on 12/22/2009 10:30 AM 

In a previous post, I showed one method for updating a SharePoint list with data from another SharePoint list. The example illustrated moving data from an existing text field to a custom field.  In the project this field was a custom type, containing a text box to hold a value and a dropdown list to hold a unit of measure. This blog entry will be about creating that custom field.

This custom field isn’t anything fancy: a text box and a dropdown. The method to create and test the control used in this post may seem like overkill, but it translates well to more complex scenarios. You can create custom fields in code but in some cases, such as when working with multiple fields or post backs etc, I find it easier to use a control. This custom field is going to be created with a user control.

I am going to create my control in a website and then incorporate it in a SharePoint project.  First, I started Visual Studio and created new website. Next, I created a new application in IIS under my SharePoint site and pointed it at this website. With a site in place, I can create my control, add it to a test page and when satisfied with the look, copy it into my SharePoint custom field project.

 
The screen shot below shows the default page as it displays in a browser after adding our control to the page. The control contains a text box for an amount and a dropdown for units (mcg, mg, g, ml, oz, caps, and tabs).  One thing to note in the control is the absence of a code behind reference.

Once the control is created it is time to create the SharePoint project. I started Visual Studio and from the File menu created a new project called Blog.Entry.CustomField.UnitOfMeasure: File --> New--> Project-->SharePoint-->Empty. Once the project was created, I right clicked on Blog.Entry.CustomField.UnitOfMeasure and selected Add--> New Item-->SharePoint-->Field Control.  The result is found below:

 
Some housekeeping is in order before we add our control. Take a minute to browse to wherever your 12 hive is contained - in my case C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES. Here you will see the server control templates that exist in your SharePoint installation. When finished, this custom field control will be added to this folder.

We need to mirror this hierarchy in our project. Add a 12 folder to the project and move the Templates folder inside. Rename Templates to TEMPLATE and add another directory underneath that is called CONTROLTEMPLATES. Next, in file manager browse to the BlogEntryUnitOfMeasure.ascx from our MySandbox website. Right click on the control, choose copy, go back to your SharePoint project, right click on the CONTROLTEMPLATES directory and choose paste. Finally, delete the BlogEntryUnitOfMeasure.ascx.cs file that appeared when you added the control to this project. We don’t need the code behind. Your project now looks like this:
 

All the definitions for fields that ship with SharePoint are defined in the 12 hive - in my case C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML\FLDTYPES.XML. This custom field type needs to have a definition in the same directory. The file fldtypes_Blog.Entry.CustomField.UnitOfMeasure.xml  is that definition.

Before editing fldtypes_Blog.Entry.CustomField.UnitOfMeasure.xml the project needs to be signed, build, and the assembly’s public key token discovered. The public key will be needed for the field type definition.Right click on the solution and choose properties. Select the Signing tab and under Choose a strong name key file select New. The dialogue box you see below will appear. Give your key a name and click OK.
 
Visual Studio generates a key when the project is created, but the GUID is not unique - it is the same for every key Visual Studio creates with a  project. You always want a unique GUID for the assembly.
 
To discover the public key token after the build, open a command prompt and browse to the folder containing the DLL. In my case that is C:\SharePoint\Blog.Projects\Blog.Entry.CustomField.UnitOfMeasure\Blog.Entry.CustomField.UnitOfMeasure\bin\Debug. Type SN.exe -Tp Blog.Entry.CustomField.UnitOfMeasure.dll and hit return. You will see something like the screen shot below.

 
My Public key token is b7add9a5cd512803.

With the public key token at our disposal, we can now create the field type definition. As you can see below, when the FieldTypeClass is defined the Public Key Token from above is used.
 
 

Now we can code the classes. Visual Studio framed out two classes Blog.Entry.CustomField.UnitOfMeasure.Field.cs  and Blog.Entry.CustomField.UnitOfMeasure.FieldControl.cs. There is only one small change to make to Blog.Entry.CustomField.UnitOfMeasure.Field.cs. Because our custom field has multiple columns (values) we need to change class BlogEntryCustomFieldUnitOfMeasureField : SPFieldText to class BlogEntryCustomFieldUnitOfMeasureField : Microsoft.SharePoint.SPFieldMultiColumn. The entire class is below.

The classes BlogEntryCustomFieldUnitOfMeasureFieldControl and BlogEntryCustomFieldUnitOfMeasureFieldValue are going to do most of the heavy lifting, such that it is in this case.

Visual Studio created a Blog.Entry.CustomField.UnitOfMeasure.FieldControl.cs file but didn’t really add too much. Right at the start we need to change  class BlogEntryCustomFieldUnitOfMeasureFieldControl : TextField to class BlogEntryCustomFieldUnitOfMeasureFieldControl : BaseFieldControl, IDesignTimeHtmlProvider. Visual Studio create a defaulted TextField and we needed to change it to a BaseFieldControl. Next we want to declare a variable for fields and override the DefaultTemplate to point at the server control we created. Then override CreateChildControls to make sure we find the textbox and dropdown controls in the template (server control) that is loaded. If the controls are not found an exception is thrown:
 
 

Of course, we need to get and set the value of these fields The field.Units and field.UnitOfMeasure are declared in the next and final class we have to code Blog.Entry.CustomField.UnitOfMeasure.FieldValue

 

 

As was said above, we create the Blog.Entry.CustomField.UnitOfMeasure.FieldValue class which will pull the values together. Here we set the base of the control to two fields and setting the Units textbox as the first field and the Units of measure dropdown as the second. This should make the get and set of field.Units and field.UnitOfMeasure in BlogEntryCustomFieldUnitOfMeasureFieldControl clear.

 

After all that, build and deploy the solution.You should see BlogEntryUnitOfMeasure.ascx in 12\TEMPLATE\CONTROLTEMPLATES and  fldtypes_Blog.Entry.CustomField.UnitOfMeasure.xml in \12\TEMPLATE\XML.

I had set up a test site to deploy the project and in this site created a Sample list. Below are screen shots of the Create Column and add New Item pages.
 

 
 

Tags:

Your name:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment   Cancel  
Search our site
 GO
Cleveland
2221 Professor Avenue
Cleveland, Ohio 44113
216.522.9740