locked
The correct way to use SPFieldMultiColumn (in custom field type) RRS feed

  • Question

  • Hi all,

    I'm having a strange problem with my custom field type. This has been working without problems up until I realised that I also needed to collect another piece of information in the field.  I changed the field class to inherit from SPFieldMultiColumn.

    My problem is that I'm getting an invalid cast exception.  This is my stack trace:

    [InvalidCastException: Unable to cast object of type 'BCA_ReadAndSignDocuments.DocumentField' to type 'Microsoft.SharePoint.SPFieldUser'.]
       Microsoft.SharePoint.WebControls.UserField.CreateChildControls() +1054
       System.Web.UI.Control.EnsureChildControls() +87
       Microsoft.SharePoint.WebControls.BaseFieldControl.OnLoad(EventArgs e) +176
       System.Web.UI.Control.LoadRecursive() +50
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Control.LoadRecursive() +141
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
    
    


     

    I have a people picker and a textbox in my rendering template (as follows)

    <%@ Control Language="C#" Debug="true" %>
    <%@ 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" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    
    <SharePoint:RenderingTemplate runat="server" ID="DocumentFieldRendering">
        <Template>
            <table class="ms-authoringcontrols">
                <tr>
                    <td><SharePoint:UserField ID="fldUser" runat="server" /></td>
                </tr>
                <tr>
                    <td>Message to Signers</td>
                </tr>
                <tr>
                    <td><asp:TextBox ID="txtMessage" runat="server" Height="200" Width="400" TextMode="MultiLine" /></td>
                </tr>
        </Template>
    </SharePoint:RenderingTemplate>
    


     

    My field class is as follows:

    using System;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using Microsoft.SharePoint.Security;
    
    namespace BCA_ReadAndSignDocuments
    {
        [CLSCompliant(false)]
        [Guid("d4904a21-4999-438c-b8b7-560782ae71d0")]
        public class DocumentField : SPFieldMultiColumn
        {
            public DocumentField(SPFieldCollection fields, string fieldName)
                : base(fields, fieldName)
            {
            }
            
            public DocumentField(SPFieldCollection fields, string typeName, string displayName)
                : base(fields, typeName, displayName)
            {
            }
    
            public override BaseFieldControl FieldRenderingControl
            {
                [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
                get
                {
                    BaseFieldControl fieldControl = new DocumentFieldControl();
                    fieldControl.FieldName = InternalName;
                    return fieldControl;
                }
            }
        }
    }
    
    


     

    And my field control class is as follows:

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using System.Web.UI.WebControls;
    
    namespace BCA_ReadAndSignDocuments
    {
        [CLSCompliant(false)]
        [Guid("ddf68607-a8e4-4271-ae29-2168498476e3")]
        public class DocumentFieldControl : BaseFieldControl
        {
            protected override string DefaultTemplateName
            {
                get
                {
                    return "DocumentFieldRendering";
                }
            }
    
            public override object Value
            {
                get
                {
                    EnsureChildControls();
                    UserField fldUser = TemplateContainer.FindControl("fldUser") as UserField;
                    TextBox txtMessage = TemplateContainer.FindControl("txtMessage") as TextBox;
                    SPFieldMultiColumnValue mcv = new SPFieldMultiColumnValue(2);
                    mcv[0] = fldUser.Value as string;
                    mcv[1] = txtMessage.Text;
                    return mcv;
                }
                set
                {
                    EnsureChildControls();
                    UserField fldUser = TemplateContainer.FindControl("fldUser") as UserField;
                    TextBox txtMessage = TemplateContainer.FindControl("txtMessage") as TextBox;
                    SPFieldMultiColumnValue mcv = this.ItemFieldValue as SPFieldMultiColumnValue;
                    fldUser.Value = mcv[0];
                    txtMessage.Text = mcv[1];
                }
            }
        }
    }
    

    I have already been through the following tutorial with a fine tooth comb and cannot see anything missing:  http://msdn.microsoft.com/en-us/magazine/dd727508.aspx 

    Any ideas are warmly welcomed. 

    Tuesday, January 3, 2012 12:07 PM

Answers

  • Got it now I think.

    I shouldn't have been adding field controls to my rendering template.

    Instead of

    <SharePoint:UserField ID="fldUser" runat="server" />

    I should have had

    <SharePoint:PeopleEditor ID="fldUser" runat="server" />

    This is all still a bit new for me :S

    • Marked as answer by HairyMike Tuesday, January 3, 2012 3:05 PM
    Tuesday, January 3, 2012 3:04 PM