ユーザー設定フィールド型を作成する

最終更新日: 2010年6月25日

適用対象: SharePoint Foundation 2010

この記事の内容
プロジェクトをセットアップする
検証規則クラスを作成する
ユーザー設定フィールド クラスを作成する
フィールド レンダリング コントロールを作成する
フィールド レンダリング テンプレートを作成する
フィールド型定義を作成する
XSLT スタイルシートを作成する
ユーザー設定フィールド型をビルドしてテストする
モバイル デバイス向けフィールド レンダリングとコンピュータ向けフィールド レンダリングの違い

このトピックでは、ユーザー設定フィールド型を作成する方法を手順を追って説明します。ここでは、10 桁の国際標準図書番号 (ISBN) を保持することを目的としたフィールドを作成します。

ユーザー設定フィールド型を作成し、そのレンダリングを定義する手順の概要については、「[方法] ユーザー設定フィールド型を作成する」を参照してください。

前提条件

Microsoft Visual Studio 2010

プロジェクトをセットアップする

ユーザー設定フィールド プロジェクトをセットアップするには

  1. Visual Studio で、空の SharePoint プロジェクトを作成し、そのプロジェクトをサンドボックス ソリューションではなくファーム ソリューションにして、ISBN_Field_Type という名前を付けます。

  2. [ソリューション エクスプローラー] でプロジェクト名を右クリックし、[プロパティ] を選択します。

  3. [プロパティ] ダイアログの [アプリケーション] タブで、[アセンブリ名] に「Contoso.SharePoint.ISBN_Field_Type」、[既定の名前空間] に「Contoso.SharePoint」と入力します。[対象とする Framework] は .NET Framework 3.5 のままにしておきます。

  4. Visual Studio の [標準メニュー] の [ソリューション プラットフォーム] ボックスに "Any CPU" または "x64" と表示されていない場合は、[ビルド] タブを開いて、[プラットフォーム ターゲット] を "Any CPU" または "x64" のどちらかに設定します。この選択については、「[方法] 適切なターゲット フレームワークおよび CPU を設定する」を参照してください。

  5. ツール バーの [すべてを保存] をクリックします。

  6. [ソリューション エクスプローラー] でプロジェクト名を右クリックし、[追加]、[新しいアイテム] の順に選択します。

  7. [新しいアイテムの追加] ダイアログ ボックスの [インストールされているテンプレート] ツリーで、[Visual Basic] (または [Visual C#])、[コード] の順に選択します。

  8. [テンプレート] ボックスで [クラス] を選択し、[名前] ボックスに、「ISBN.Field.cs (または ISBN.Field.vb)」と入力して、[追加] をクリックします。

  9. 2 つ目のクラスを作成する場合は、前の手順を繰り返します。ただし、[名前] ボックスには、「ISBN.FieldControl.cs (または ISBN.FieldControl.vb)」と入力し、[追加] をクリックします。

  10. 3 つ目のクラスも同様に追加します。[名前] ボックスには、「ISBN10ValidationRule.cs (または ISBN10ValidationRule.vb)」と入力し、[追加] をクリックします。

  11. [ソリューション エクスプローラー] で、プロジェクト名を右クリックし、[追加] を選択して、[SharePoint のマップされたフォルダー] を選択します。

  12. 表示されたツリー コントロールを使用して、フォルダーを TEMPLATE\ControlTemplates にマップして、[OK] をクリックします。

  13. [ソリューション エクスプローラー] で、プロジェクト名ではなく [ControlTemplates] フォルダーを右クリックし、[追加]、[新しいアイテム] の順に選択します。

  14. [新しい項目の追加] ダイアログ ボックスの [インストールされているテンプレート] ツリーで、[SharePoint]、[2010] の順に選択します。

  15. [テンプレート] ボックスで SharePoint の [ユーザー コントロール] を選択し、ascx ファイルに「ISBNFieldControl.ascx」という名前を付けて、[追加] をクリックします。ファイルが自動的に SharePoint ソリューション マニフェストに追加され、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates に展開されるように設定されます。また、アセンブリがマニフェストに追加され、グローバル アセンブリ キャッシュ (GAC) に展開されるように設定されます。

    ヒントヒント

    [ソリューション エクスプローラー] でプロジェクト名を右クリックして [ユーザー コントロール] を追加しないでください。この方法で [ユーザー コントロール] を追加すると、コントロールは TEMPLATE\ControlTemplates のサブフォルダーに追加され、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates の対応するサブフォルダーに展開されます (コントロールを移動しなかった場合)。サブフォルダーのレンダリング テンプレートは読み込まれません。

  16. ISBNFieldControl.ascx ファイルの下に自動的に作成された ISBNFieldControl.ascx.cs および ISBNFieldControl.ascx.designer.cs ファイル (または ISBNFieldControl.ascx.vb および ISBNFieldControl.ascx.designer.vb ファイル) を削除します。これらのファイルはこのプロジェクトでは必要ありません。ISBNFieldControl.ascx の既定のコンテンツは、削除した ISBNFieldControl.ascx.cs (または ISBNFieldControl.ascx.vb) ファイルを参照するので、この時点でプロジェクトをビルドすると、ファイルが見つからないことを示す警告がコンパイラによって表示されます。既定のコンテンツはこのトピックの後の手順で変更するので、この警告は無視してください。

  17. [ソリューション エクスプローラー] で、プロジェクト名を右クリックし、[追加] を選択して、[SharePoint のマップされたフォルダー] を選択します。

  18. 表示されたツリー コントロールを使用して、フォルダーを TEMPLATE\XML にマップして、[OK] をクリックします。

  19. [ソリューション エクスプローラー] で、プロジェクト名ではなく [XML] フォルダーを右クリックし、[追加]、[新しいアイテム] の順に選択します。

  20. [新しいアイテムの追加] ダイアログ ボックスの [テンプレート] ウィンドウで、[Visual C#] (または [Visual Basic])、[データ]、[XML ファイル] の順に選択します。

  21. [名前] ボックスに「fldtypes_ISBNField.xml」と入力し、[追加] をクリックします。

  22. [ソリューション エクスプローラー] で、プロジェクト名を右クリックし、[追加] を選択して、[SharePoint のマップされたフォルダー] を選択します。

  23. 表示されたツリー コントロールを使用して、フォルダーを TEMPLATE\LAYOUTS\XSL にマップして、[OK] をクリックします。

  24. [ソリューション エクスプローラー] で、プロジェクト名ではなく [XSL] フォルダーを右クリックし、[追加]、[新しいアイテム] の順に選択します。

  25. [新しいアイテムの追加] ダイアログ ボックスの [テンプレート] ウィンドウで、[Visual C#] (または [Visual Basic])、[データ]、[XSLT ファイル] の順に選択します。

  26. [名前] ボックスに「fldtypes_ISBNField.xsl」と入力し、[追加] をクリックします。これは、前に作成したファイルの名前と非常に似ていることに注意してください。2 つのファイルの目的は異なっており、別々のフォルダーに展開されます。このトピックの作業を進める際、この 2 つのファイルは区別するようにしてください。

  27. [ソリューション エクスプローラー] で [参照設定] ノードを右クリックし、[参照の追加] をクリックします。[参照の追加] ダイアログ ボックスの [.NET] タブで [PresentationFramework.dll] を選択し、[OK] をクリックします (このアセンブリには、次の手順で作成する ValidationRule クラスの定義が含まれています)。

検証規則クラスを作成する

検証規則クラスを作成するには

  1. ISBN10ValidationRule.cs (または ISBN10ValidationRule.vb) ファイルを開き、次のステートメントを追加します。

    using System.Text.RegularExpressions;
    using System.Windows.Controls;
    using System.Globalization;
    
    Imports System.Text.RegularExpressions
    Imports System.Windows.Controls
    Imports System.Globalization
    
  2. Namespace Naming Guidelines (英語)」のガイドラインに準拠するように名前空間を変更します。このチュートリアルでは、Contoso.System.Windows.Controls を使用します。

  3. クラス宣言を次のコードに置き換えます。

    public class ISBN10ValidationRule : ValidationRule
    {
        private const Int32 ISBNMODULO = 11;
    
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            String iSBN = (String)value;
            String errorMessage = "";
    
            Regex rxISBN = new Regex(@"^(?'GroupID'\d{1,5})-(?'PubPrefix'\d{1,7})-(?'TitleID'\d{1,6})-(?'CheckDigit'[0-9X]{1})$");
    
            if (!rxISBN.IsMatch(iSBN))
            {
                errorMessage = "An ISBN must have this structure:\n1-5 digit Group ID, hyphen, \n1-7 digit Publisher Prefix, hyphen, \n1-6 digit Title ID, hyphen, \n1 Check Digit (which can be \"X\" to indicate \"10\").\n";
            }
    
            if (errorMessage == "") // Matched the RegEx, so check for group length errors.
            {
                Match mISBN = rxISBN.Match(iSBN);
                GroupCollection groupsInString = mISBN.Groups;
    
                String groupID = groupsInString["GroupID"].Value;
                String pubPrefix = groupsInString["PubPrefix"].Value;
    
                if ((groupID.Length + pubPrefix.Length) >= 9)
                {
                    errorMessage = "The Group ID and Publisher Prefix can total no more than 8 digits.\n";
                }
    
                String titleID = groupsInString["TitleID"].Value;
    
                if (((groupID.Length + pubPrefix.Length) + titleID.Length) != 9)
                {
                    errorMessage = errorMessage + "The Group ID, Publisher Prefix, and \nTitle ID must total exactly 9 digits.\n";
                }
    
                if (errorMessage == "") //No group length errors, so verify the check digit algorithm.
                {
                    Int32 checkDigitValue;
                    String checkDigit = groupsInString["CheckDigit"].Value;
    
                    // To ensure check digit is one digit, "10" is represented by "X".
                    if (checkDigit == "X")
                    {
                        checkDigitValue = 10;
                    }
                    else
                    {
                        checkDigitValue = Convert.ToInt32(checkDigit);
                    }
    
                    String iSBN1st3Groups = groupID + pubPrefix + titleID; //Concatenate without the hyphens.
    
                    // Sum the weighted digits.
                    Int32 weightedSum = (10 * Convert.ToInt32(iSBN1st3Groups.Substring(0, 1))) +
                                         (9 * Convert.ToInt32(iSBN1st3Groups.Substring(1, 1))) +
                                         (8 * Convert.ToInt32(iSBN1st3Groups.Substring(2, 1))) +
                                         (7 * Convert.ToInt32(iSBN1st3Groups.Substring(3, 1))) +
                                         (6 * Convert.ToInt32(iSBN1st3Groups.Substring(4, 1))) +
                                         (5 * Convert.ToInt32(iSBN1st3Groups.Substring(5, 1))) +
                                         (4 * Convert.ToInt32(iSBN1st3Groups.Substring(6, 1))) +
                                         (3 * Convert.ToInt32(iSBN1st3Groups.Substring(7, 1))) +
                                         (2 * Convert.ToInt32(iSBN1st3Groups.Substring(8, 1))) +
                                          checkDigitValue;
    
                    Int32 remainder = weightedSum % ISBNMODULO;  // ISBN is invalid if weighted sum modulo 11 is not 0.
    
                    if (remainder != 0)
                    {
                        errorMessage = "Number fails Check Digit verification.";
                    }
    
                    if (errorMessage == "") // Passed check digit verification. 
                    {
                        return new ValidationResult(true, "This is a valid ISBN.");
                    }// end check digit verification passed
    
                    else // the check digit verification failed
                    {
                        return new ValidationResult(false, errorMessage);
                    }
    
                }// end no group length errors
    
                else // There was some error in a group length
                {
                    return new ValidationResult(false, errorMessage);
                }
    
            }// end RegEx match succeeded
    
            else // There was a RegEx match failure
            {
                  return new ValidationResult(false, errorMessage);
            }
    
        }// end Validate method 
    
    }// end ISBN10ValidationRule class
    
    Public Class ISBN10ValidationRule
        Inherits ValidationRule
        Private Const ISBNMODULO As Int32 = 11
    
        Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As CultureInfo) As ValidationResult
            Dim iSBN As String = CType(value, String)
            Dim errorMessage As String = ""
    
            Dim rxISBN As New Regex("^(?'GroupID'\d{1,5})-(?'PubPrefix'\d{1,7})-(?'TitleID'\d{1,6})-(?'CheckDigit'[0-9X]{1})$")
    
            If Not rxISBN.IsMatch(iSBN) Then
                errorMessage = "An ISBN must have this structure:" & vbLf & "1-5 digit Group ID, hyphen, " & vbLf & "1-7 digit Publisher Prefix, hyphen, " & vbLf & "1-6 digit Title ID, hyphen, " & vbLf & "1 Check Digit (which can be ""X"" to indicate ""10"")." & vbLf
            End If
    
            If errorMessage = "" Then ' Matched the RegEx, so check for group length errors.
                Dim mISBN As Match = rxISBN.Match(iSBN)
                Dim groupsInString As GroupCollection = mISBN.Groups
    
                Dim groupID As String = groupsInString("GroupID").Value
                Dim pubPrefix As String = groupsInString("PubPrefix").Value
    
                If (groupID.Length + pubPrefix.Length) >= 9 Then
                    errorMessage = "The Group ID and Publisher Prefix can total no more than 8 digits." & vbLf
                End If
    
                Dim titleID As String = groupsInString("TitleID").Value
    
                If ((groupID.Length + pubPrefix.Length) + titleID.Length) <> 9 Then
                    errorMessage = errorMessage & "The Group ID, Publisher Prefix, and " & vbLf & "Title ID must total exactly 9 digits." & vbLf
                End If
    
                If errorMessage = "" Then 'No group length errors, so verify the check digit algorithm.
                    Dim checkDigitValue As Int32
                    Dim checkDigit As String = groupsInString("CheckDigit").Value
    
                    ' To ensure check digit is one digit, "10" is represented by "X".
                    If checkDigit = "X" Then
                        checkDigitValue = 10
                    Else
                        checkDigitValue = Convert.ToInt32(checkDigit)
                    End If
    
                    Dim iSBN1st3Groups As String = groupID & pubPrefix & titleID 'Concatenate without the hyphens.
    
                    ' Sum the weighted digits.
                    Dim weightedSum As Int32 = (10 * Convert.ToInt32(iSBN1st3Groups.Substring(0, 1))) + (9 * Convert.ToInt32(iSBN1st3Groups.Substring(1, 1))) + (8 * Convert.ToInt32(iSBN1st3Groups.Substring(2, 1))) + (7 * Convert.ToInt32(iSBN1st3Groups.Substring(3, 1))) + (6 * Convert.ToInt32(iSBN1st3Groups.Substring(4, 1))) + (5 * Convert.ToInt32(iSBN1st3Groups.Substring(5, 1))) + (4 * Convert.ToInt32(iSBN1st3Groups.Substring(6, 1))) + (3 * Convert.ToInt32(iSBN1st3Groups.Substring(7, 1))) + (2 * Convert.ToInt32(iSBN1st3Groups.Substring(8, 1))) + checkDigitValue
    
                    Dim remainder As Int32 = weightedSum Mod ISBNMODULO ' ISBN is invalid if weighted sum modulo 11 is not 0.
    
                    If remainder <> 0 Then
                        errorMessage = "Number fails Check Digit verification."
                    End If
    
                    If errorMessage = "" Then ' Passed check digit verification.
                        Return New ValidationResult(True, "This is a valid ISBN.") ' end check digit verification passed
    
                    Else ' the check digit verification failed
                        Return New ValidationResult(False, errorMessage)
                    End If
                    ' end no group length errors
    
                Else ' There was some error in a group length
                    Return New ValidationResult(False, errorMessage)
                End If
                ' end RegEx match succeeded
    
            Else ' There was a RegEx match failure
                Return New ValidationResult(False, errorMessage)
            End If
    
        End Function ' end Validate method
    
    End Class ' end ISBN10ValidationRule class
    

    作成した検証規則クラスには、詳細な検証ロジックがすべて保持されます。検証規則クラスの詳細については、System.Text.RegularExpressions および ValidationRule を参照してください。

ユーザー設定フィールド クラスを作成する

ユーザー設定フィールド クラスを作成するには

  1. ISBN.Field.cs (または ISBN.Field.vb) ファイルを開きます。

  2. 次のステートメントを追加します。

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using Microsoft.SharePoint.Security;
    
    using System.Windows.Controls;
    using System.Globalization;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    
    Imports Microsoft.SharePoint
    Imports Microsoft.SharePoint.WebControls
    Imports Microsoft.SharePoint.Security
    
    Imports System.Windows.Controls
    Imports System.Globalization
    Imports System.Runtime.InteropServices
    Imports System.Security.Permissions
    
  3. 次のステートメントを追加します。このステートメントにより、クラス実装が、後の手順で作成する他のクラスを参照できます。これらのクラスを作成するまで、ステートメントに関するコンパイラの警告が表示される場合があります。

    using Contoso.SharePoint.WebControls;
    using Contoso.System.Windows.Controls;
    
    Imports Contoso.SharePoint.WebControls
    Imports Contoso.System.Windows.Controls
    
  4. 名前空間が Contoso.SharePoint であることを確認します。

  5. クラスの名前が ISBNField であることを確認し、そのクラスが SPFieldText から継承するようにクラスの宣言を変更します。

    public class ISBNField : SPFieldText
    {
    }
    
    Public Class ISBNField
        Inherits SPFieldText
    
    End Class
    
  6. クラスに必要な次のコンストラクターを追加します。

    public ISBNField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
    {
    }
    
    public ISBNField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
    {
    }
    
    Public Sub New(fields as SPFieldCollection, fieldname as String)
            MyBase.New(fields, fieldName)
    End Sub
    
    Public Sub New(fields as SPFieldCollection, typeName as String, displayName as String)
            MyBase.New(fields, typeName, displayName)
    End Sub
    
  7. FieldRenderingControl の次のオーバーライドをクラスに追加します。ISBNFieldControl は、後の手順で作成するクラスです。

    public override BaseFieldControl FieldRenderingControl
    {
         [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        get
        {
            BaseFieldControl fieldControl = new ISBNFieldControl();
            fieldControl.FieldName = this.InternalName;
    
            return fieldControl;
        }
    }
    
    Public Overrides ReadOnly Property FieldRenderingControl() As BaseFieldControl
        Get
            Dim fieldControl As BaseFieldControl = New ISBNFieldControl()
            fieldControl.FieldName = Me.InternalName
            Return fieldControl
        End Get
    End Property
    
  8. 次の GetValidatedString メソッドのオーバーライドを ISBNField クラスに追加します。

    public override string GetValidatedString(object value)
    {
        if ((this.Required == true)
           &&
           ((value == null)
            ||
           ((String)value == "")))
        {
            throw new SPFieldValidationException(this.Title 
                + " must have a value.");
        }
        else
        {
            ISBN10ValidationRule rule = new ISBN10ValidationRule();
            ValidationResult result = rule.Validate(value, CultureInfo.InvariantCulture);
    
            if (!result.IsValid)
            {
                throw new SPFieldValidationException((String)result.ErrorContent);
            }
            else
            {
                return base.GetValidatedString(value);
            }
        }
    }// end GetValidatedString
    
    Public Overrides Function GetValidatedString(ByVal value As Object) As String
        If (Me.Required = True) AndAlso ((value Is Nothing) OrElse (CType(value, String) = "")) Then
            Throw New SPFieldValidationException(Me.Title & " must have a value.")
        Else
            Dim rule As New ISBN10ValidationRule()
            Dim result As ValidationResult = rule.Validate(value, cultureInfo.InvariantCulture)
    
            If Not result.IsValid Then
                Throw New SPFieldValidationException(CType(result.ErrorContent, String))
            Else
                Return MyBase.GetValidatedString(value)
            End If
        End If
    End Function ' end GetValidatedString
    

    次に示すように、このオーバーライドは、GetValidatedString のオーバーライドの一般的なパターンを示しています。

    • GetValidatedString メソッドのオーバーライドは、フィールドが必須かどうかをチェックし、必須であれば、値が null または空の String のときに SPFieldValidationException 例外をスローします。この例外は、ユーザーが作成または編集したリスト アイテムを保存しようとしたときに、[新しいアイテム] ページおよび [アイテムの編集] ページでキャッチされます。この場合、ページは開いたままになり、この例外の Message() プロパティによって、空のフィールドの下にエラー メッセージが表示されます。

    • 値が無効である場合、GetValidatedString のオーバーライドは SPFieldValidationException をスローします。これにより、無効なフィールドの下にエラー メッセージが表示されます。

    • 値がユーザー設定の入力規則を通過すると、GetValidatedString のオーバーライドは基本 GetValidatedString を呼び出します。

  9. ファイルを保存して閉じます。

フィールド レンダリング コントロールを作成する

フィールド レンダリング コントロールを作成するには

  1. ISBN.FieldControl.cs (または ISBN.FieldControl.vb) ファイルを開きます。

  2. 次のステートメントを追加します。

    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    using System.Runtime.InteropServices;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    
    Imports System.Runtime.InteropServices
    Imports Microsoft.SharePoint
    Imports Microsoft.SharePoint.WebControls
    
  3. 名前空間を Contoso.SharePoint.WebControls に変更します。

  4. クラスの名前が ISBNFieldControl であることを確認し、そのクラスが TextField から継承するようにクラスの宣言を変更します。

    public class ISBNFieldControl : TextField
    {
    }
    
    Public Class ISBNFieldControl 
        Inherits TextField
    
    End Class
    
  5. ASP.NET の Label Web コントロールの保護されたフィールドを追加します。このフィールドは、新規モードまたは編集モードでレンダリングするときに、各 ISBN 番号の前に "ISBN" というプレフィックスを追加します。ISBN 番号自体を保持するために、保護された TextBox フィールドを追加する必要はありません。このカスタムの ISBNFieldControl は、TextField からこのフィールドを継承するためです。

    protected Label ISBNPrefix;
    
    Protected Label ISBNPrefix
    
  6. ASP.NET Label Web コントロールの別の保護されたフィールドを追加します。このフィールドは、表示モードでフィールドの現在の値をレンダリングします。

    protected Label ISBNValueForDisplay;
    
    Protected Label ISBNValueForDisplay
    
  7. 次に、DefaultTemplateName プロパティの次のオーバーライドを追加します。このプロパティに割り当てる String は、前に作成した ascx ファイルに後で追加する RenderingTemplate オブジェクトの ID です (このファイルは、プロジェクトの完了時に、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\CONTROLTEMPLATES フォルダーに配置されます)。この例では、ControlTemplateTemplate、または TemplateName はオーバーライドしないので、RenderingTemplate は次のように呼び出されることになります。ControlTemplateTemplate を返し、これは次に TemplateName によって名前が指定されたすべての RenderingTemplateTemplate プロパティを返します。最後に、TemplateName の get アクセサーが DefaultTemplateName を返します。新規モード用と編集モード用にそれぞれ別のテンプレートがある場合など、さらに複雑なケースでは、上記の 1 つ以上のプロパティと、場合によっては AlternateTemplateName プロパティまたは DefaultAlternateTemplateName プロパティをオーバーライドする必要があります。

    protected override string DefaultTemplateName
    {
        get
        {
            if (this.ControlMode == SPControlMode.Display)
            {
                return this.DisplayTemplateName;
            }
            else
            {
                return "ISBNFieldControl";
            }         
        }
    }
    
    Protected Overrides ReadOnly Property DefaultTemplateName() As String
        Get
            If Me.ControlMode = SPControlMode.Display Then
                Return Me.DisplayTemplateName
            Else
                Return "ISBNFieldControl"
        End Get
    End Property
    
  8. DisplayTemplateName の次のオーバーライドを追加します。このプロパティに割り当てる String は、前に作成した ascx ファイルに後で追加する RenderingTemplate オブジェクトの ID です。このオブジェクトによって、フィールド値が表示モードでレンダリングされます。

    public override string DisplayTemplateName
    {
        get
        {
            return "ISBNFieldControlForDisplay";
        }
        set
        {
            base.DisplayTemplateName = value;
        }
    }
    
    Public Overrides Property DisplayTemplateName() As String
        Get
                 Return "ISBNFieldControlForDisplay"
        End Get
        Set
                 MyBase.DisplayTemplateName = Value
        End Set
    End Property
    
  9. CreateChildControls メソッドの次のオーバーライドを追加します。基になる ISBNField が null の場合、このオーバーライドは何も実行しません (null になるのは、ISBNFieldControl が ISBNField の FieldRenderingControl プロパティの set アクセサーとは関係なく作成されている場合です。ISBN.Field.cs (または ISBN.Field.vb) の FieldRenderingControl のオーバーライドを参照してください)。

    protected override void CreateChildControls()
    {
        if (this.Field != null)
        {
    
    
        }// end if there is a non-null underlying ISBNField 
    
      // Do nothing if the ISBNField is null.
    }
    
    Protected Overrides Sub CreateChildControls()
        If Me.Field IsNot Nothing Then
    
        End If ' end if there is a non-null underlying ISBNField
    
        ' Do nothing if the ISBNField is null or control mode is Display.
    End Sub
    
  10. 条件の最初の行として、基本メソッドの次の呼び出しを追加します。継承された子コントロールが、テンプレートではなく、基本 CreateChildControls によって全体的または部分的にレンダリングされる場合に確実に作成されるように、通常、このような呼び出しが必要となります。たとえば、(%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates にある) DefaultTemplates.ascx 内の "TextField" テンプレートは、子 TextBox をレンダリングしますが、CreateChildControls メソッドは、基になる SPFieldText フィールドの最大サイズに合わせて TextBox の最大サイズを調整します。基本 CreateChildControls は、動的な BaseValidator コントロールを作成する場合もあります。ただし、通常は基本メソッドのソース コードにはアクセスできないため、基本メソッドを呼び出す必要があるかどうか、また、必要がある場合はオーバーライドのどの場所で呼び出せばよいかを判断するために、実験してみる必要があります。

    // Make sure inherited child controls are completely rendered.
    base.CreateChildControls();
    
    ' Make sure inherited child controls are completely rendered.
    MyBase.CreateChildControls()
    
  11. 次の行を追加して、レンダリング テンプレート内の子コントロールを、ユーザー設定フィールド コントロールで宣言された (またはその親から継承した) 子コントロール フィールドに関連付けます。このレンダリング テンプレートは現時点でこの関連付けをしておく必要があります。基本 CreateChildControls を呼び出すと、継承された子コントロールは、カスタム レンダリング テンプレートではなく、ユーザー設定フィールド クラスの親が使用するレンダリング テンプレートに関連付けられるので、この基本の関連付けを新しい関連付けで置き換える必要があるためです。

    // Associate child controls in the .ascx file with the 
    // fields allocated by this control.
    this.ISBNPrefix = (Label)TemplateContainer.FindControl("ISBNPrefix");
    this.textBox = (TextBox)TemplateContainer.FindControl("TextField");
    this.ISBNValueForDisplay = (Label)TemplateContainer.FindControl("ISBNValueForDisplay");
    
    ' Associate child controls in the .ascx file with the 
    ' fields allocated by this control.
    Me.ISBNPrefix = CType(TemplateContainer.FindControl("ISBNPrefix"), Label)
    Me.textBox = CType(TemplateContainer.FindControl("TextField"), TextBox)
    Me.ISBNValueForDisplay = CType(TemplateContainer.FindControl("ISBNValueForDisplay"), Label)
    
  12. コントロールの関連付けコードの下に、次の構造を追加します。フィールドでは、表示モードでレンダリング テンプレートを使用する必要があります (このテンプレートはこのトピックの後の手順で作成します)。これは、新規モードおよび編集モードで使用するものとは異なります。このため、モードに応じて異なる子コントロールが初期化されます。

    if (this.ControlMode != SPControlMode.Display)
    {
    
    }
    else // control mode is Display 
    {                 
    
    }// end control mode is Display
    
    If Not Me.ControlMode = SPControlMode.Display Then
    
    Else ' control mode is display
    
    End If ' end control mode is Display
    
  13. 前の手順で作成した条件構造の "if" (または "If") 句内に、次の内部条件構造を追加します。ポストバックで再初期化を実行すると、子コントロールの値に対してユーザーが加えた変更がすべて取り消されるため、コードではポストバックで何も実行しないようにします。

    if (!this.Page.IsPostBack)
    {
    
    }// end if this is not a postback 
    
    //Do not reinitialize on a postback.
    
    If Not Me.Page.IsPostBack Then
    
    End If ' end if this is not a postback
    
    'Do not reinitialize on a postback.
    
  14. 前の手順で追加した条件構造内に、コントロール モードが New (新規) のときに TextBox 子コントロールを既定の ISBN 値で初期化する次の内部条件を追加します。

    if (this.ControlMode == SPControlMode.New)
    {
        textBox.Text = "0-000-00000-0";
    
    } // end assign default value in New mode
    
    If Me.ControlMode = SPControlMode.New Then
       textBox.Text = "0-000-00000-0"
    
    End If ' end assign default value in New mode
    
  15. コントロール モードが表示のときに実行される else (または Else) ブロックで、次のコードを追加して、フィールドをコンテンツ データベースから現在の値に初期化します。

    // Assign current value from database to the label control
    ISBNValueForDisplay.Text = (String)this.ItemFieldValue;
    
    ' Assign current value from database to the label control
    ISBNValueForDisplay.Text = CType(Me.ItemFieldValue, String)
    
  16. OnLoad メソッドは、ISBNFieldControl.Value を、コンテンツ データベースに現在のフィールド値を保持する ItemFieldValue の値に初期化するため、編集モードでは何も実行する必要はありません。この時点で、CreateChildControls のオーバーライドは次のようになります。

    protected override void CreateChildControls()
    {
        if (this.Field != null)
        {
            // Make sure inherited child controls are completely rendered.
            base.CreateChildControls();
    
            // Associate child controls in the .ascx file with the 
            // fields allocated by this control.
            this.ISBNPrefix = (Label)TemplateContainer.FindControl("ISBNPrefix");
            this.textBox = (TextBox)TemplateContainer.FindControl("TextField");
            this.ISBNValueForDisplay = (Label)TemplateContainer.FindControl("ISBNValueForDisplay");
    
            if (this.ControlMode != SPControlMode.Display)
            {
                if (!this.Page.IsPostBack)
                {
                    if (this.ControlMode == SPControlMode.New)
                    {
                        textBox.Text = "0-000-00000-0";
    
                    } // end assign default value in New mode
    
                 }// end if this is not a postback 
    
              // Do not reinitialize on a postback.
    
            }// end if control mode is not Display
            else // control mode is Display 
            {                 
                // Assign current value from database to the label control
                ISBNValueForDisplay.Text = (String)this.ItemFieldValue;
    
            }// end control mode is Display
    
        }// end if there is a non-null underlying ISBNField 
    
        // Do nothing if the ISBNField is null.
    }
    
    Protected Overrides Sub CreateChildControls()
        If Me.Field IsNot Then
            ' Make sure inherited child controls are completely rendered.
            MyBase.CreateChildControls()
    
            ' Associate child controls in the .ascx file with the 
            ' fields allocated by this control.
            Me.ISBNPrefix = CType(TemplateContainer.FindControl("ISBNPrefix"), Label)
            Me.textBox = CType(TemplateContainer.FindControl("TextField"), TextBox)
            Me.ISBNValueForDisplay = CType(TemplateContainer.FindControl("ISBNValueForDisplay"), Label)
    
            If Not Me.ControlMode = SPControlMode.Display Then
    
                 If Not Me.Page.IsPostBack Then
                     If Me.ControlMode = SPControlMode.New Then
                         textBox.Text = "0-000-00000-0"
    
                     End If ' end assign default value in New mode
    
                 End If ' end if this is not a postback
    
                 'Do not reinitialize on a postback.
    
            Else ' control mode is display
                ' Assign current value from database to the label control
                ISBNValueForDisplay.Text = CType(Me.ItemFieldValue, String)
    
            End If ' end control mode is Display
    
        End If ' end if there is a non-null underlying ISBNField
    
        ' Do nothing if the ISBNField is null or control mode is Display.
    End Sub
    
  17. Value プロパティの次のオーバーライドを追加します。このプロパティは、UI 内のフィールドの値です。エンド ユーザーが値を変更し、まだ保存していない場合、Value プロパティは、基になる ISBNField (SPFieldText から派生) オブジェクトの実際の値、またはコンテンツ データベースに格納されたフィールド値であるとは限りません。get アクセサーと set アクセサーの両方で、まず EnsureChildControls を呼び出します (このメソッドは、必要に応じて CreateChildControls を呼び出します)。(1) 最初に基本プロパティを呼び出す、(2) 基本プロパティの set アクセサーと get アクセサーが EnsureChildControls を呼び出すことがわかっている、という場合を除き、EnsureChildControls の呼び出しは必須です。TextField から継承した基になる TextBox 子コントロールをまったく別の種類のコントロール (ドロップダウン リスト ボックスなど) で置き換えている場合、Value プロパティのオーバーライドの set アクセサーと get アクセサーでは、基本プロパティを呼び出すのではなく、そのコントロールを直接設定する必要があります。コントロールが最初に基になる ISBNField オブジェクトの値を確実に読み込むように、OnLoad() メソッドは、ISBNFieldControl.Value を ItemFieldValue (基になる ISBNField オブジェクトの値) の値に設定します。

    public override object Value
    {
        get
        {
            EnsureChildControls();
            return base.Value;
        }
        set
        {
             EnsureChildControls();
             base.Value = (String)value;
             // The value of the ISBNPrefix field is hardcoded in the
             // template, so it is not set here.
        }
    }
    
    Public Overrides Property Value() As Object
        Get
            EnsureChildControls()
            Return MyBase.Value
        End Get
        Set(ByVal value As Object)
            EnsureChildControls()
            MyBase.Value = CType(value, String)
            ' The value of the ISBNPrefix field is hardcoded in the
            ' template, so it is not set here.
        End Set
    End Property
    

フィールド レンダリング テンプレートを作成する

レンダリング テンプレートを作成するには

  1. ISBNFieldControl.ascx ファイルを開きます。

  2. 次のディレクティブが既にファイルに存在します。

    <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
    <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
    <%@ Import Namespace="Microsoft.SharePoint" %> 
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    
  3. このマークアップの下には <%@ Control ディレクティブがあり、これは前の手順で削除したファイルを参照します。また、このディレクティブには、このプロジェクトでは使用されていない属性が含まれます。これを次の簡略化されたディレクティブに置き換えます。

    <%@ Control Language="C#" %>
    
  4. ディレクティブの下に、次のマークアップを追加します。

    <SharePoint:RenderingTemplate ID="ISBNFieldControl" runat="server">
      <Template>
        <asp:Label ID="ISBNPrefix" Text="ISBN" runat="server" />
        &nbsp;
        <asp:TextBox ID="TextField" runat="server"  />
      </Template>
    </SharePoint:RenderingTemplate>
    

    このマークアップについて、次の点に注意してください。

    • RenderingTemplate の ID は、DefaultTemplateName プロパティのオーバーライドで使用した文字列と同じである必要があります。

    • Label コントロールの Text 属性は、変更されることがないため、テンプレートのここで設定します。

    • HTML の "&nbsp;" 要素は、2 つのコントロールの間に配置します。

    • TextBox の定義は、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx に定義されている "TextField" RenderingTemplate の定義と同じです。ただし、DefaultTemplateName のオーバーライドで、"TextField" テンプレートではなく、このカスタム テンプレートを指しているため、この定義をここで繰り返す必要があります。基本 CreateChildControls メソッド (上記参照) はこの ID でコントロールを参照するので、カスタム テンプレートでも同じ ID を使用します。

  5. 次の追加 RenderingTemplate を最初のもののすぐ下に追加します。

    <SharePoint:RenderingTemplate ID="ISBNFieldControlForDisplay" runat="server">
      <Template>
        <asp:Label ID="ISBNValueForDisplay" runat="server" />
      </Template>
    </SharePoint:RenderingTemplate>
    

    この RenderingTemplate は、CreateChildControls メソッドによって、表示モードの既定のテンプレートとして指定されます。

フィールド型定義を作成する

フィールド型定義を作成するには

  1. Visual Studio でプロジェクトをビルドします。プロジェクトは完成していませんが、アセンブリの GUID と公開キー トークンを生成するために、この時点でビルドする必要があります。

  2. fldtypes_ISBNField.xml ファイルを開き、そのコンテンツを次のマークアップに置き換えます。

    <?xml version="1.0" encoding="utf-8" ?>
    <FieldTypes>
      <FieldType>
        <Field Name="TypeName">ISBN</Field>
        <Field Name="ParentType">Text</Field>
        <Field Name="TypeDisplayName">ISBN</Field>
        <Field Name="TypeShortDescription">ISBN for a book</Field>
        <Field Name="UserCreatable">TRUE</Field>
        <Field Name="ShowOnListCreate">TRUE</Field>
        <Field Name="ShowOnSurveyCreate">TRUE</Field>
        <Field Name="ShowOnDocumentLibraryCreate">TRUE</Field>
        <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
        <Field Name="FieldTypeClass">Contoso.SharePoint.ISBNField, $SharePoint.Project.AssemblyFullName$</Field>
      </FieldType>
    </FieldTypes>
    

    このファイルは、SharePoint Foundation のユーザー設定フィールド型を定義するものです。要素の目的と意味の詳細については、「[方法] ユーザー設定フィールド型の定義を作成する」、「FldTypes.xml ファイルについて」、「FieldTypes 要素 (フィールド型)」、「FieldType 要素 (フィールド型)」、および「Field 要素 (フィールド型)」を参照してください。<Field Name="FieldTypeClass"> 要素は、1 行で記述する必要があります。

  3. <Field Name="FieldTypeClass"> 要素の値は、ユーザー設定フィールド クラスの完全修飾名の後にコンマと Visual Studio 2010 トークン ($SharePoint.Project.AssemblyFullName$) が続きます。プロジェクトのコンパイル時にこのファイルのコピーが作成され、そのコピー内でトークンが 4 つの部分で構成される完全なアセンブリ名に置き換えられます。Visual Studio 2010 の Visual Studio [ビルド] メニューから [ソリューションの展開] を選択したときに展開されるのは、このコピーです。Visual Studio 2010 を使用しない場合、パブリック キー トークンを生成するには、プロジェクトが完了していなくても、この時点でプロジェクトをコンパイルする必要があります。その後、「[方法] アセンブリの完全な名前を取得するツールを作成する」で説明したツールを使用して、4 つの部分で構成される完全な名前を取得し、それをトークンの代わりに手動で貼り付けることができます。

XSLT スタイルシートを作成する

XSLT スタイルシートを作成するには

  • fldtypes_ISBNField.xsl ファイルを開き、<?xml version="1.0" encoding="utf-8"?> タグの下にあるすべてのものを、次のマークアップに置き換えます。

    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
                    xmlns:d="https://schemas.microsoft.com/sharepoint/dsp"
                    version="1.0"
                    exclude-result-prefixes="xsl msxsl ddwrt"
                    xmlns:ddwrt="https://schemas.microsoft.com/WebParts/v2/DataView/runtime"
                    xmlns:asp="https://schemas.microsoft.com/ASPNET/20"
                    xmlns:__designer="https://schemas.microsoft.com/WebParts/v2/DataView/designer" 
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                    xmlns:SharePoint="Microsoft.SharePoint.WebControls"
                    xmlns:ddwrt2="urn:frontpage:internal">
    
      <xsl:template match="FieldRef[@Name = 'ISBN']" mode="Text_body">
    
        <xsl:param name="thisNode" select="." /> 
    
        <span style="background-color:lightgreen;font-weight:bold">
    
          <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" />
    
        </span>
    
      </xsl:template >
    
    </xsl:stylesheet>
    

    XSLT スタイルシートは、リスト ビューのフィールドをレンダリングします。リスト ビューの ISBN 列のセルの背景は薄い緑色で、ISBN 値は太字で表示されます。

    リスト ビュー モードの列ヘッダーは、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATES\LAYOUTS\XSL の組み込みファイル fldtypes.xsl によって提供される別の XSLT スタイルシートによってレンダリングされます。

ユーザー設定フィールド型をビルドしてテストする

ユーザー設定フィールド型をビルドしてテストするには

  1. [ビルド] メニューの [展開] をクリックします。これにより、アセンブリが自動的にリビルドされ GAC に展開されます。また、ascx ファイルは %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates に、fldtypes*.xml ファイルは %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\XML に、fldtypes*.xsl ファイルは %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL に展開され、Web アプリケーションが再利用されます。

    注意

    開発環境がマルチサーバー ファームの場合、自動的には展開されません。ソリューションである isbn_field_type.wsp は、サーバーの全体管理アプリケーションの [ソリューションの管理] ページから、または SharePoint 管理シェルのコマンドレットで展開します。

  2. SharePoint Web アプリケーションで Web サイトを開き、"Books" というリストを作成します。

  3. 新しい列をリストに追加します。[列の作成] ページで、列名として「ISBN」と入力します。

  4. [ISBN for a book] に対応するオプション ボタンをクリックします。

  5. [はい] をクリックして、フィールドを必須にします。

  6. [既定のビューに追加] チェック ボックスはオンのままにしておきます。

  7. [OK] をクリックします。

  8. アイテムをリストに追加します。

  9. [新しいアイテム] ページで、フィールドが最初は既定値である "0-000-00000-0" に設定されていること、また、フィールドのタイトルが "ISBN" で、新規モードおよび編集モードのレンダリング テンプレートで定義されているように、値の前に "ISBN" があることを確認します。

  10. 無効な ISBN 値を入力して、アイテムを保存しようとしたときにどのようなエラーが発生するかどうかを確認します。

  11. フィールドを完全に空のままにした場合に、どのようなことが起こるかどうかを確認します。

  12. 最後に、「0-262-61108-2」と入力するか、有効であることがわかっている別の値を入力し、[保存] をクリックします (有効な ISBN に対してエラーが発生した場合は、値の末尾にスペースが入っていないかどうかを確認してください)。

  13. リスト ビューの値が太字になっていること、また背景が薄い緑色であることを確認します。

  14. アイテムのタイトルをクリックして、表示ページを開きます。フィールドが、コンテンツ データベースの現在の値でレンダリングを行っていることを確認します。フィールド タイトルである "ISBN" が存在しますが、編集モードおよび新規モードのように値自体の前に "ISBN" がないことに注意してください。これは、このプレフィックスは、表示モードのレンダリング テンプレートに含まれていなかったためです。

  15. [アイテムの編集] をクリックし、フィールドを編集します。フィールドが最初は既定値ではなく現在の値に設定されていること、また、フィールドのタイトルが "ISBN" で、新規モードおよび編集モードのレンダリング テンプレートで定義されているように、値の前に "ISBN" があることを確認します。

  16. フィールド値を無効な値に変更し、新規モードの場合と同様に編集モードでも検証エラーが表示されることを確認します。

モバイル デバイス向けフィールド レンダリングとコンピュータ向けフィールド レンダリングの違い

SharePoint Foundation では、モバイル デバイス用のユーザー設定フィールド レンダリング コントロールによるフィールドのレンダリングは、コンピューター用のユーザー設定フィールド レンダリング コントロールによるフィールドのレンダリングと似ていますが、次の相違点に注意してください。

  • モバイル ページは、コンピュータのブラウザ用に設計されている SharePoint Foundation サイトのメイン ページとはまったく異なるページ セットであり、RenderingTemplate オブジェクトの別のセットを参照します。

  • モバイルの RenderingTemplate オブジェクトは、DefaultTemplates.ascx ではなく、MobileDefaultTemplates.ascx および GbwMobileDefaultTemplates.ascx で宣言されます。

  • モバイルのフィールド レンダリング コントロールは、Microsoft.SharePoint.MobileControls という独自の名前空間を持ち、ASP.NET の System.Web.UI.WebControls 名前空間ではなく、System.Web.UI.MobileControls 名前空間のクラスから派生します。

  • モバイルのフィールド レンダリング コントロールの継承階層は、標準のフィールド レンダリング コントロールの継承階層とは若干異なります。たとえば、標準のフィールド レンダリングの TemplateBasedControlFormComponent の機能は、SPMobileComponent クラスに組み込まれています。

  • モバイル コンテキスト用に作成したユーザー設定フィールド レンダリング コントロールは、コンピュータのブラウザ用に作成したユーザー設定フィールド レンダリング コントロールの場合と比べ、フィールドをレンダリングするときに、コントロールの CreateChildControls メソッドへの依存度が高く、その分レンダリング テンプレートへの依存度は低くなります。また、モバイルのユーザー設定レンダリング コントロールを開発するときには、CreateChildControls メソッド自体をオーバーライドすることはあまりありません。代わりに、モバイルのユーザー設定レンダリング コントロールでは、CreateChildControls メソッドによって呼び出される次の 4 つのメソッドの中から 1 つ以上のメソッドをオーバーライドするのが一般的です。

関連項目

参照

FieldTypes 要素 (フィールド型)

FieldType 要素 (フィールド型)

Field 要素 (フィールド型)

Namespace Naming Guidelines

RenderPattern 要素 (フィールド型)

AlternateTemplateName

BaseValidator

ControlTemplate

CreateChildControls

DefaultAlternateTemplateName

DefaultTemplateName

EnsureChildControls

FieldRenderingControl

GetValidatedString

ItemFieldValue

Label

OnLoad()

RegularExpressions

RenderingTemplate

SPControlMode

SPFieldText

SPFieldValidationException

Template

TemplateName

TextBox

TextField

ValidationRule

Value

概念

[方法] ユーザー設定フィールド クラスを作成する

[方法] ユーザー設定フィールド型の定義を作成する

ユーザー設定フィールド型の展開

ユーザー設定フィールド データ入力規則

[方法] フィールド レンダリング コントロールを作成する

[方法] フィールド レンダリング テンプレートを作成する

[方法] ユーザー設定フィールド型を作成する

ソリューションの概要