Create a new C#
Class Library project in Visual Studio .NET. After created, add a reference
toMicrosoft.SharePoint.dll and System.Web.dll. Sign your project with a new key
to make your assembly strong named.
PublicColumnValue.cs
Add a class called PublishColumnValue and let it inherit
from SPFieldMultiChoiceValue. Create two constructors:
****************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Web.UI;
using Microsoft.SharePoint.WebControls;
namespace Etter.Column {
public class
PublishColumnValue : SPFieldMultiChoiceValue {
public
PublishColumnValue()
: base() {
}
public
PublishColumnValue( string value )
: base(
value ) {
}
}
}
***************************************************************
PublicColumn.cs
Add a class called PublishColumn and let it inherit from
SPFieldMultiChoice. Create two constructors:
***************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace Etter.Column {
public class
PublishColumn : SPFieldMultiChoice {
public
PublishColumn( SPFieldCollection fields, string fieldName )
: base(
fields, fieldName ) {
}
public
PublishColumn( SPFieldCollection fields, string typeName, string displayName )
: base(
fields, typeName, displayName ) {
}
}
}
Override the GetFieldValue property, which will return the
new PublicColumnValue type:
public override object GetFieldValue( string value ) {
if( string.IsNullOrEmpty( value ) ) {
return null;
}
return new
PublishColumnValue( value );
}
*****************************************************************
The last thing you have to do in this class is overriding
the FieldRenderingControl property. This property tells SharePoint which
control to use to render the field:
public override BaseFieldControl FieldRenderingControl {
get {
BaseFieldControl control = new PublishColumnControl();
control.FieldName = InternalName;
return control;
}
}
******************************************************************
PublishColumnControl.ascx
Now this is a C# Class Library project, so you need to add
an ascx-file not by clicking Add > New Item, but by copying an ascx-file
from some other project and replace the content by:
<%@ Control Language="C#"
Debug="true" %>
<%@Assembly Name="Microsoft.SharePoint,
Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@Register TagPrefix="SharePoint"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<SharePoint:RenderingTemplate
ID="PublishColumnRendering" runat="server">
<Template>
<asp:CheckBoxList ID="cblLocations"
runat="server" />
</Template>
</SharePoint:RenderingTemplate>
PublishColumnControl.cs
Add a new class called PublishColumnControl and make it
inherit from BaseFieldControl. Also declare the checkbox we are going to use:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
namespace Etter.Column {
protected CheckBoxList cblLocations;
public class PublishColumnControl : BaseFieldControl {
}
}
*************************************************************
To tell SharePoint which rendering template to use, override
the DefaultTemplateName property and return the ID of the RenderingTemplate in
PublishColumnControl.ascx:
protected override string DefaultTemplateName {
get {
return "PublishColumnRendering"; }
}
Override the CreateChildControls method so we can get a
reference to the cblLocations checkboxlist and change some properties:
protected override void CreateChildControls() {
if( Field == null ) {
return;
}
base.CreateChildControls();
if(
ControlMode == SPControlMode.Display ) {
return;
}
cblLocations =
TemplateContainer.FindControl( "cblLocations" ) as CheckBoxList;
if(
cblLocations == null ) {
throw
new ArgumentException( "cblLoations could not be found" );
}
cblLocations.TabIndex = TabIndex;
cblLocations.CssClass = CssClass;
cblLocations.Items.Add( new ListItem( "item 1" ) );
cblLocations.Items.Add( new ListItem( "item 3" ) );
cblLocations.Items.Add( new ListItem( "item 2" ) );
}
First we check if the Field is not null and if the control
is not in display mode (we define the rendering of the display mode in the
fldtypes_PublishColumn.xml file). After that we try to get a reference to the
checkboxlist, set some properties and add list items.
Last but not least we are going to override the Value
property which sets and gets the value of the field type as a
PublishColumnValue object:
public override object Value {
get {
EnsureChildControls();
PublishColumnValue fieldValue = new PublishColumnValue();
foreach( ListItem item in cblLocations.Items ) {
if( item.Selected ) {
fieldValue.Add( item.Value );
}
}
return
fieldValue;
}
set {
EnsureChildControls();
cblLocations.ClearSelection();
PublishColumnValue fieldValue = (PublishColumnValue)value;
for(
int i = 0; i < fieldValue.Count; i++ ) {
string s = fieldValue[i];
if( cblLocations.Items.FindByValue( s ) != null ) {
cblLocations.Items.FindByValue( s ).Selected = true;
}
}
}
}
*************************************************************
Fldtypes_PublishColumn.xml
Add a xml file fldtypes_PublishColumn.xml. This xml file
will hold the field type definition which SharePoint needs for every field.
<?xmlversion="1.0"encoding="utf-8"
?>
<FieldTypes>
<FieldType>
<FieldName="TypeName">PublishColumn</Field>
<FieldName="ParentType">MultiChoice</Field>
<FieldName="TypeDisplayName">Publish</Field>
<FieldName="TypeShortDescription">Publish
location</Field>
<FieldName="UserCreatable">TRUE</Field>
<FieldName="ShowOnListAuthoringPages">TRUE</Field>
<FieldName="ShowOnDocumentLibraryAuthoringPages">TRUE</Field>
<FieldName="ShowOnSurveyAuthoringPages">TRUE</Field>
<FieldName="ShowOnColumnTemplateAuthoringPages">TRUE</Field>
<FieldName="FieldTypeClass">Etter.Column.PublishColumn,
Etter.Column, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7331c42d890b827</Field>
<PropertySchema>
<Fields>
</Fields>
</PropertySchema>
<RenderPatternName="DisplayPattern">
<ColumnHTMLEncode="TRUE"/>
</RenderPattern>
</FieldType>
</FieldTypes>
The FieldTypeClass has the following format: <namespace
and class>,<full strong name assembly>. RenderPattern holds de
definition that will be used to render the field in display mode.
Deploying to SharePoint
Of course it would be the best if you add this field type to
a feature and deploy it with a solution package, but for now I will explain how
to deploy it by hand:
• Build
your C# class library project and deploy the assembly to the GAC.
• Copy the
PublishColumnControl.ascx file to the c:\program files\Common files\microsoft
shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\ folder.
• Copy the
fldtypes_PublishColumn.xml file to the c:\program files\Common files\microsoft
shared\web server extensions\12\TEMPLATE\XML\ folder.
• IISRESET.
Open a list on your SharePoint portal and add a new column
based on the PublishColumn you created.