Create custom field type
2007-05-05 20:28
453 查看
Create custom field type in WSS V3
WSS v3 supports creating custom field type with OM, and you have total control on its internal data storage, editing and display. I have tested it today by creating a custom phone number field with 3 sub-fields: country code, area code and phone number.
1. Create a ascx control and its code behind for editing
In order to make the custom field type editable in form view, we need to custom rendering user control for this new field type. At first, we need to create an ascx file with a Sharepoint RenderingTemplate control on it. See the code below.
<%@ Control Language="C#" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<SharePoint:RenderingTemplate ID="PhoneNumberFieldRendering" runat="server">
<Template>
+<asp:TextBox ID="txtCountryCode" runat="server" MaxLength="3" Size="3"></asp:TextBox>(<asp:TextBox ID="txtAreaCode" runat="server" MaxLength="3" Size="3"></asp:TextBox>)<asp:TextBox ID="txtNumber" runat="server" MaxLength="8" Size="8"></asp:TextBox>
</Template>
</SharePoint:RenderingTemplate>
Then we need to implement its code behind class. The class must derives BaseFieldControl and overrides the property Value to set the three fields of a phone number into three segments in SPFieldMultiColumnValue object.
public class PhoneNumberFieldControl : Microsoft.SharePoint.WebControls.BaseFieldControl
{
protected System.Web.UI.WebControls.TextBox txtCountryCode;
protected System.Web.UI.WebControls.TextBox txtAreaCode;
protected System.Web.UI.WebControls.TextBox txtNumberCode;
protected override string DefaultTemplateName
{
get
{
return "PhoneNumberFieldControl";
}
}
public override object Value
{
get
{
EnsureChildControls();
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = new Microsoft.SharePoint.SPFieldMultiColumnValue(3);
phoneNumberValue[0] = txtCountryCode.Text.Trim();
phoneNumberValue[1] = txtAreaCode.Text.Trim();
phoneNumberValue[2] = txtNumberCode.Text.Trim();
return phoneNumberValue;
}
set
{
EnsureChildControls();
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = value as Microsoft.SharePoint.SPFieldMultiColumnValue;
txtCountryCode.Text = phoneNumberValue[0];
txtAreaCode.Text = phoneNumberValue[1];
txtNumberCode.Text = phoneNumberValue[2];
}
}
public override void Focus()
{
EnsureChildControls();
txtCountryCode.Focus();
}
protected override void CreateChildControls()
{
if (Field == null) return;
base.CreateChildControls();
if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.Display)
return;
txtCountryCode = (System.Web.UI.WebControls.TextBox)FindControl("txtCountryCode");
if (txtCountryCode == null) throw new NullReferenceException("txtCountryCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtCountryCode.TabIndex = TabIndex;
txtCountryCode.CssClass = CssClass;
txtCountryCode.ToolTip = Field.Title + " Country Code";
txtAreaCode = (System.Web.UI.WebControls.TextBox)FindControl("txtAreaCode");
if (txtAreaCode == null) throw new NullReferenceException("txtAreaCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtAreaCode.TabIndex = TabIndex;
txtAreaCode.CssClass = CssClass;
txtAreaCode.ToolTip = Field.Title + " Area Code";
txtNumberCode = (System.Web.UI.WebControls.TextBox)FindControl("txtNumberCode");
if (txtNumberCode == null) throw new NullReferenceException("txtNumberCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtNumberCode.TabIndex = TabIndex;
txtNumberCode.CssClass = CssClass;
txtNumberCode.ToolTip = Field.Title + " Phone Number";
if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.New)
{
txtCountryCode.Text = Field.GetCustomProperty("DefaultCountryCode").ToString();
txtAreaCode.Text = Field.GetCustomProperty("DefaultAreaCode").ToString();
txtNumberCode.Text = Field.GetCustomProperty("DefaultNumber").ToString();
}
}
}
2. Create a custom field type class
The custom field type must inherit the base class SPField. In my test, I wrote following class derives SPFieldMultiColumn which is a subclass of SPField but supports multiple sub-columns. GetValidatedString overridden method checks the input object value and return its string value if it’s correct. GetFieldValue method is to create a SPFieldMultiColumnValue object by the input string. FieldRenderingControl property returns the user control we created in step 1.
public class PhoneNumberField : Microsoft.SharePoint.SPFieldMultiColumn
{
public PhoneNumberField(Microsoft.SharePoint.SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public PhoneNumberField(Microsoft.SharePoint.SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}
public override string GetValidatedString(object value)
{
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = value as Microsoft.SharePoint.SPFieldMultiColumnValue;
if (phoneNumberValue == null)
return String.Empty;
if(String.IsNullOrEmpty(phoneNumberValue[0]) || String.IsNullOrEmpty(phoneNumberValue[1]) || String.IsNullOrEmpty(phoneNumberValue[2]))
throw new Microsoft.SharePoint.SPFieldValidationException(Microsoft.SharePoint.SPResource.GetString(Microsoft.SharePoint.Strings.MissingRequiredField));
return value.ToString();
}
public override object GetFieldValue(string value)
{
if (String.IsNullOrEmpty(value))
return null;
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = new Microsoft.SharePoint.SPFieldMultiColumnValue(value);
return phoneNumberValue;
}
public override Microsoft.SharePoint.WebControls.BaseFieldControl FieldRenderingControl
{
get
{
Microsoft.SharePoint.WebControls.BaseFieldControl phoneNumberFieldControl = new PhoneNumberFieldControl();
return base.FieldRenderingControl;
}
}
}
3. Create custom Field Type Definition
The custom type must include a custom field type definition. It’s an XML file with file name fldtypes_*.xml. I named my phone number field definition file as fldtypes_phonenumber.xml. The detail schema is in http://msdn2.microsoft.com/en-us/library/ms415141.aspx
<?xml version="1.0" encoding="utf-8"?>
<FieldTypes>
<FieldType>
<Field Name="TypeName">PhoneNumber</Field>
<Field Name="ParentType">MultiColumn</Field>
<Field Name="TypeDisplayName">Phone Number</Field>
<Field Name="TypeShortDescription">Phone Number</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="ShowInListCreate">TRUE</Field>
<Field Name="ShowInSurveyCreate">TRUE</Field>
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
<Field Name="FieldTypeClass">WSSFieldDemo.PhoneNumberField,WSSFieldDemo,Version=1.0.0.0,Culture=neutral,PublicKeyToken=5cca1e4ab4efce28</Field>
<PropertySchema>
<Fields>
<Field Name="DefaultCountryCode" DisplayName="Default Country Code" MaxLength="3" DisplaySize="3" Type="Text">
<Default>1</Default>
</Field>
<Field Name="DefaultAreaCode" DisplayName="Default Area Code" MaxLength="3" DisplaySize="3" Type="Text">
<Default>416</Default>
</Field>
<Field Name="DefaultNumber" DisplayName="Default Phone Number" MaxLength="8" DisplaySize="8" Type="Text">
<Default>5325554</Default>
</Field>
</Fields>
</PropertySchema>
<RenderPattern Name="DisplayPattern">
<Switch>
<Expr>
<Column />
</Expr>
<Case Value="" />
<Default>
<HTML><![CDATA[+]]></HTML>
<Column SubColumnNumber="0" HTMLEncode="TRUE" />
<HTML><![CDATA[(]]></HTML>
<Column SubColumnNumber="1" HTMLEncode="TRUE" />
<HTML><![CDATA[)]]></HTML>
<Column SubColumnNumber="2" HTMLEncode="TRUE" />
</Default>
</Switch>
</RenderPattern>
</FieldType>
</FieldTypes>
4. Deployment
The final step is to deploy the assembly, user control and the field definition xml. It includes following steps:
1. Build the solution and sign the assembly
2. Put the assembly into GAC
3. Copy the user control to /program files/.../web server extensions/12/template/controltemplates
4. Copy fldtypes_phonenumber.xml to /program files/.../web server extensions/12/template/xml/
5. iisreset.
WSS v3 supports creating custom field type with OM, and you have total control on its internal data storage, editing and display. I have tested it today by creating a custom phone number field with 3 sub-fields: country code, area code and phone number.
1. Create a ascx control and its code behind for editing
In order to make the custom field type editable in form view, we need to custom rendering user control for this new field type. At first, we need to create an ascx file with a Sharepoint RenderingTemplate control on it. See the code below.
<%@ Control Language="C#" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<SharePoint:RenderingTemplate ID="PhoneNumberFieldRendering" runat="server">
<Template>
+<asp:TextBox ID="txtCountryCode" runat="server" MaxLength="3" Size="3"></asp:TextBox>(<asp:TextBox ID="txtAreaCode" runat="server" MaxLength="3" Size="3"></asp:TextBox>)<asp:TextBox ID="txtNumber" runat="server" MaxLength="8" Size="8"></asp:TextBox>
</Template>
</SharePoint:RenderingTemplate>
Then we need to implement its code behind class. The class must derives BaseFieldControl and overrides the property Value to set the three fields of a phone number into three segments in SPFieldMultiColumnValue object.
public class PhoneNumberFieldControl : Microsoft.SharePoint.WebControls.BaseFieldControl
{
protected System.Web.UI.WebControls.TextBox txtCountryCode;
protected System.Web.UI.WebControls.TextBox txtAreaCode;
protected System.Web.UI.WebControls.TextBox txtNumberCode;
protected override string DefaultTemplateName
{
get
{
return "PhoneNumberFieldControl";
}
}
public override object Value
{
get
{
EnsureChildControls();
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = new Microsoft.SharePoint.SPFieldMultiColumnValue(3);
phoneNumberValue[0] = txtCountryCode.Text.Trim();
phoneNumberValue[1] = txtAreaCode.Text.Trim();
phoneNumberValue[2] = txtNumberCode.Text.Trim();
return phoneNumberValue;
}
set
{
EnsureChildControls();
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = value as Microsoft.SharePoint.SPFieldMultiColumnValue;
txtCountryCode.Text = phoneNumberValue[0];
txtAreaCode.Text = phoneNumberValue[1];
txtNumberCode.Text = phoneNumberValue[2];
}
}
public override void Focus()
{
EnsureChildControls();
txtCountryCode.Focus();
}
protected override void CreateChildControls()
{
if (Field == null) return;
base.CreateChildControls();
if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.Display)
return;
txtCountryCode = (System.Web.UI.WebControls.TextBox)FindControl("txtCountryCode");
if (txtCountryCode == null) throw new NullReferenceException("txtCountryCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtCountryCode.TabIndex = TabIndex;
txtCountryCode.CssClass = CssClass;
txtCountryCode.ToolTip = Field.Title + " Country Code";
txtAreaCode = (System.Web.UI.WebControls.TextBox)FindControl("txtAreaCode");
if (txtAreaCode == null) throw new NullReferenceException("txtAreaCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtAreaCode.TabIndex = TabIndex;
txtAreaCode.CssClass = CssClass;
txtAreaCode.ToolTip = Field.Title + " Area Code";
txtNumberCode = (System.Web.UI.WebControls.TextBox)FindControl("txtNumberCode");
if (txtNumberCode == null) throw new NullReferenceException("txtNumberCode is null. Corrupted PhoneNumberFieldControl.ascx file.");
txtNumberCode.TabIndex = TabIndex;
txtNumberCode.CssClass = CssClass;
txtNumberCode.ToolTip = Field.Title + " Phone Number";
if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.New)
{
txtCountryCode.Text = Field.GetCustomProperty("DefaultCountryCode").ToString();
txtAreaCode.Text = Field.GetCustomProperty("DefaultAreaCode").ToString();
txtNumberCode.Text = Field.GetCustomProperty("DefaultNumber").ToString();
}
}
}
2. Create a custom field type class
The custom field type must inherit the base class SPField. In my test, I wrote following class derives SPFieldMultiColumn which is a subclass of SPField but supports multiple sub-columns. GetValidatedString overridden method checks the input object value and return its string value if it’s correct. GetFieldValue method is to create a SPFieldMultiColumnValue object by the input string. FieldRenderingControl property returns the user control we created in step 1.
public class PhoneNumberField : Microsoft.SharePoint.SPFieldMultiColumn
{
public PhoneNumberField(Microsoft.SharePoint.SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public PhoneNumberField(Microsoft.SharePoint.SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}
public override string GetValidatedString(object value)
{
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = value as Microsoft.SharePoint.SPFieldMultiColumnValue;
if (phoneNumberValue == null)
return String.Empty;
if(String.IsNullOrEmpty(phoneNumberValue[0]) || String.IsNullOrEmpty(phoneNumberValue[1]) || String.IsNullOrEmpty(phoneNumberValue[2]))
throw new Microsoft.SharePoint.SPFieldValidationException(Microsoft.SharePoint.SPResource.GetString(Microsoft.SharePoint.Strings.MissingRequiredField));
return value.ToString();
}
public override object GetFieldValue(string value)
{
if (String.IsNullOrEmpty(value))
return null;
Microsoft.SharePoint.SPFieldMultiColumnValue phoneNumberValue = new Microsoft.SharePoint.SPFieldMultiColumnValue(value);
return phoneNumberValue;
}
public override Microsoft.SharePoint.WebControls.BaseFieldControl FieldRenderingControl
{
get
{
Microsoft.SharePoint.WebControls.BaseFieldControl phoneNumberFieldControl = new PhoneNumberFieldControl();
return base.FieldRenderingControl;
}
}
}
3. Create custom Field Type Definition
The custom type must include a custom field type definition. It’s an XML file with file name fldtypes_*.xml. I named my phone number field definition file as fldtypes_phonenumber.xml. The detail schema is in http://msdn2.microsoft.com/en-us/library/ms415141.aspx
<?xml version="1.0" encoding="utf-8"?>
<FieldTypes>
<FieldType>
<Field Name="TypeName">PhoneNumber</Field>
<Field Name="ParentType">MultiColumn</Field>
<Field Name="TypeDisplayName">Phone Number</Field>
<Field Name="TypeShortDescription">Phone Number</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="ShowInListCreate">TRUE</Field>
<Field Name="ShowInSurveyCreate">TRUE</Field>
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
<Field Name="FieldTypeClass">WSSFieldDemo.PhoneNumberField,WSSFieldDemo,Version=1.0.0.0,Culture=neutral,PublicKeyToken=5cca1e4ab4efce28</Field>
<PropertySchema>
<Fields>
<Field Name="DefaultCountryCode" DisplayName="Default Country Code" MaxLength="3" DisplaySize="3" Type="Text">
<Default>1</Default>
</Field>
<Field Name="DefaultAreaCode" DisplayName="Default Area Code" MaxLength="3" DisplaySize="3" Type="Text">
<Default>416</Default>
</Field>
<Field Name="DefaultNumber" DisplayName="Default Phone Number" MaxLength="8" DisplaySize="8" Type="Text">
<Default>5325554</Default>
</Field>
</Fields>
</PropertySchema>
<RenderPattern Name="DisplayPattern">
<Switch>
<Expr>
<Column />
</Expr>
<Case Value="" />
<Default>
<HTML><![CDATA[+]]></HTML>
<Column SubColumnNumber="0" HTMLEncode="TRUE" />
<HTML><![CDATA[(]]></HTML>
<Column SubColumnNumber="1" HTMLEncode="TRUE" />
<HTML><![CDATA[)]]></HTML>
<Column SubColumnNumber="2" HTMLEncode="TRUE" />
</Default>
</Switch>
</RenderPattern>
</FieldType>
</FieldTypes>
4. Deployment
The final step is to deploy the assembly, user control and the field definition xml. It includes following steps:
1. Build the solution and sign the assembly
2. Put the assembly into GAC
3. Copy the user control to /program files/.../web server extensions/12/template/controltemplates
4. Copy fldtypes_phonenumber.xml to /program files/.../web server extensions/12/template/xml/
5. iisreset.
相关文章推荐
- About sharepoint custom FieldType bug
- SharePoint Custom Field Type与RenderTemplate ID与ascx页面无关联
- 一个简单的Checkbox Custom Field Type
- How to Add Custom Field Type (in SPFieldType Enum) Programatically or any other way
- 一个简单的Checkbox Custom Field Type
- wss custom field type
- 一个简单的Checkbox Custom Field Type
- MOSS 2007 CMS Project Technical Issues: Custom Field Type
- How to create a custom action type with a custom control (BarCheckItem), associated with it
- How To - Create a custom field using attributes of other UI objects
- 解决Custom Field Type修改时属性显示不正确的问题
- 改进:How To - Create a custom field using attributes of other UI objects
- Developing custom field type for SharePoint 201
- Create a Custom Listfield - Change Highlight Color
- Microsoft Office Project 2007 使用指南(3) - Create a custom field
- Sharepoint Custom Control Creating custom Multi Choice field type
- SharePoint基于SPFieldMultiColumn的Custom Field Type切记要覆盖GetFieldValue方法
- 用Eclipse编译android程序时,出现警告This text field does not specify an inputType or a hint
- How to create custom html helper in Asp.net MVC 3 or 4
- Custom Field Sample