Пример: создание типа настраиваемого поля

Дата последнего изменения: 25 июня 2010 г.

Применимо к: 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 в поле Пространство имен по умолчанию. В поле со списком Требуемая версия .NET Framework оставьте значение .NET Framework 3.5.

  4. Если в поле Платформы решениястандартного менюVisual Studio не указано "Любой процессор" или "x64", откройте вкладку Построение и присвойте параметру Конечная платформа значение "Любой процессор" или "x64". Сведения о том, как выбрать правильное значение, см. в статье Правильное задание конечной среды и процессора.

  5. Нажмите кнопку Сохранить все файлы на панели инструментов.

  6. Щелкните правой кнопкой мыши имя проекта в окне Обозреватель решений и выберите пункт Добавить | Создать элемент.

  7. В диалоговом окне Добавление нового элемента выберите Visual C# | Code (или Visual Basic | Code) в дереве Установленные шаблоны.

  8. В поле Шаблоны выберите Класс и затем введите ISBN.Field.cs (или ISBN.Field.vb) в поле Имя. Нажмите кнопку Добавить.

  9. Чтобы создать второй класс, повторите описанные выше действия, но при этом введите ISBN.FieldControl.cs (или ISBN.FieldControl.vb) в поле Имя. Нажмите кнопку Добавить.

  10. Аналогичным образом добавьте третий класс, указав ISBN10ValidationRule.cs (или ISBN10ValidationRule.vb) в поле Имя. Нажмите кнопку Добавить.

  11. В окне Обозреватель решений щелкните правой кнопкой мыши имя проекта, выберите команду Добавить, а затем выберите Сопоставленная папка SharePoint.

  12. С помощью элемента управления "Дерево" сопоставьте папку папке TEMPLATE\ControlTemplates и нажмите кнопку ОК.

  13. В окне Обозреватель решений щелкните правой кнопкой мыши папку ControlTemplates (не имя проекта), а затем выберите Добавить | Создать элемент.

  14. В диалоговом окне Добавление нового элемента выберите в дереве Установленные шаблоны элемент SharePoint | 2010.

  15. Выберите Пользовательский элемент управления SharePoint в поле Шаблоны и присвойте ASCX-файлу имя ISBNFieldControl.ascx. Нажмите кнопку Добавить. Visual Studio автоматически добавляет файл в манифест решения SharePoint и назначает папку развертывания %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates. Кроме того, на данном этапе в манифест добавляется сборка и назначается развертывание в глобальном кэше сборок (GAC).

    СоветСовет

    Не рекомендуется добавлять Пользовательский элемент управления, щелкнув правой кнопкой мыши имя_проекта в окне Обозреватель решений. Если для добавления пользовательского элемента управления используется этот способ, Visual Studio размещает его во вложенной папке TEMPLATE\ControlTemplates, и затем, если файл не будет перемещен, Visual Studio развернет его в соответствующей вложенной папке %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates. Шаблоны визуализации, расположенные во вложенных папках, не загружаются.

  16. Удалите файлы ISBNFieldControl.ascx.cs и ISBNFieldControl.ascx.designer.cs (или файлы ISBNFieldControl.ascx.vb и ISBNFieldControl.ascx.designer.vb), которые были созданы автоматически под файлом ISBNFieldControl.ascx. Для данного проекта эти файлы не требуются. Содержимое по умолчанию файла ISBNFieldControl.ascx относится к файлу ISBNFieldControl.ascx.cs (или файлу ISBNFieldControl.ascx.vb), который был только что удален, поэтому если на данном этапе построить проект, компилятор выдаст предупреждение о том, что требуемый файл отсутствует. Это предупреждение можно проигнорировать, поскольку содержимое по умолчанию будет изменено позднее в настоящем разделе.

  17. В окне Обозреватель решений щелкните правой кнопкой мыши имя проекта, выберите команду Добавить, а затем выберите Сопоставленная папка SharePoint.

  18. С помощью элемента управления "Дерево" сопоставьте эту папку папке TEMPLATE\XML и нажмите кнопку ОК.

  19. В окне Обозреватель решений щелкните правой кнопкой мыши новую папку XML (не имя проекта), а затем выберите Добавить | Создать элемент.

  20. В диалоговом окне Добавление нового элемента выберите Visual C# | Data (или Visual Basic | Data) и затем выберите XML-файл в окне Шаблоны.

  21. В поле Имя введите fldtypes_ISBNField.xml и нажмите кнопку Добавить.

  22. В окне Обозреватель решений щелкните правой кнопкой мыши имя проекта, выберите команду Добавить, а затем выберите Сопоставленная папка SharePoint.

  23. С помощью элемента управления "Дерево" сопоставьте эту папку папке TEMPLATE\LAYOUTS\XSL и нажмите кнопку OK.

  24. В окне Обозреватель решений щелкните правой кнопкой мыши новую папку XSL (не имя проекта), а затем выберите Добавить | Создать элемент.

  25. В диалоговом окне Добавление нового элемента выберите Visual C# | Data (или Visual Basic | Data) и затем в окне Шаблоны выберите XSLT-файл.

  26. В поле Имя введите fldtypes_ISBNField.xsl и нажмите кнопку Добавить. Обратите внимание, что это имя очень похоже на имя файла, созданного ранее. Эти файлы предназначены для разных целей и развертываются в разные папки. При работе с данным разделом храните эти файлы в разных папках.

  27. В окне Обозреватель решений щелкните правой кнопкой мыши узел Ссылки, выберите команду Добавить ссылку и затем выберите PresentationFramework.dll на вкладке .NET диалогового окна Добавление ссылки. Нажмите кнопку ОК. (Эта сборка содержит определение класса 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. Измените имя пространства имен таким образом, чтобы оно соответствовало указаниям, приведенным в статье, посвященной рекомендациям по именованию пространств имен (Возможно, на английском языке). В данном пошаговом руководстве используется имя 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 проверяют, требуется ли данное поле, и, если да, то переопределенный метод вызывает исключение SPFieldValidationException, если значение равно null или имеется пустое поле String. Это исключение перехватывается страницами Создать элемент и Изменить элемент, если пользователь пытается сохранить создаваемый или изменяемый элемент списка. В этом случае страница остается открытой, и под влиянием свойства исключения 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, которое будет являться префиксом к "ISBN", т. е. будет стоять перед номером ISBN при визуализации в режиме создания или изменения. Добавление защищенного поля TextBox для хранения номера ISBN не требуется, поскольку настраиваемое поле ISBNFieldControl наследует это поле от TextField.

    protected Label ISBNPrefix;
    
    Protected Label ISBNPrefix
    
  6. Добавьте другое защищенное поле для веб-элемента управления ASP.NET Label, который будет отображать текущее значение поля в режиме отображения.

    protected Label ISBNValueForDisplay;
    
    Protected Label ISBNValueForDisplay
    
  7. Далее добавьте следующее переопределение свойства DefaultTemplateName. Код String, который присваивается этому свойству, является идентификатором объекта RenderingTemplate, который будет создан на одном из следующих шагов, и добавлен в ASCX-файл, созданный ранее. (После завершения работы над проектом файл будет развернут в папке %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\CONTROLTEMPLATES.) Поскольку в данном примере мы не переопределяем ControlTemplate, Template или TemplateName, код RenderingTemplate будет вызываться следующим образом: ControlTemplate вернет Template, который, в свою очередь, вернет свойство Template любой сущности RenderingTemplate, имя которой содержится в коде TemplateName. Наконец, средство доступа get метода TemplateName вернет свойство DefaultTemplateName. В более сложном случае, когда, например, имеются различные шаблоны для режимов создания или изменения, придется переопределить одно или несколько предыдущих свойств, а также, возможно, свойства 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, назначаемый этому свойству, является идентификатором объекта RenderingTemplate, который будет создан на одном из следующих шагов и добавлен в ASCX-файл, созданный ранее. Этот объект отображает значение поля в режиме отображения.

    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 создается независимо от метода присвоения set для относящегося к полю ISBNField свойства FieldRenderingControl — см. переопределение FieldRenderingControl в ISBN.Field.cs (или ISBN.Field.vb).)

    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, а не шаблоном. Например, шаблон "TextField" в DefaultTemplates.ascx (из каталога %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\ControlTemplates) визуализирует дочерний элемент TextBox, а метод CreateChildControls устанавливает максимальный размер окна TextBox, чтобы оно соответствовало максимальному размеру основного поля SPFieldText. Базовый метод 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. Внутри условной структуры, добавленной на последнем шаге, добавьте следующий внутренний условный оператор, чтобы в режиме управления "Создать" инициализировать дочерний элемент управления 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, которое является значением поля в пользовательском интерфейсе. Если пользователь изменил значение и еще не сохранил его, то свойство Value не обязательно является фактическим значением основного объекта ISBNField (полученного из SPFieldText) или значением поля в базе данных контента. Обратите внимание, что как метод доступа get, так и метод доступа set начинают с вызова метода EnsureChildControls (который в случае необходимости вызовет CreateChildControls). Вызов метода EnsureChildControls обязателен, если (1) сначала не вызывается базовое свойство и (2) неизвестно, что методы доступа методов базовых свойств set и get вызывают EnsureChildControls. Если основной дочерний элемент управления TextBox, унаследованный от TextField, был заменен совершенно другим типом элемента управления, например, раскрывающимся списком, то методы доступа set и get переопределения свойства Value должны будут настроить этот элемент управления непосредственно, не вызывая базовое свойство. Чтобы гарантировать, что данный элемент управления первоначально загружается со значением из основного объекта 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>
    

    Обратите внимание на следующие моменты, связанные с этой разметкой:

    • Идентификатор ID шаблона RenderingTemplate должен быть идентичен строке, использованной в переопределении свойства DefaultTemplateName.

    • Атрибут Text элемента управления Label устанавливается здесь в шаблоне, поскольку он никогда не изменяется.

    • HTML-элемент "&nbsp;" вставляется между двумя элементами управления.

    • Определение TextBox идентично определению в поле "TextField" шаблона RenderingTemplate, заданному в файле %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx. Но это определение необходимо здесь повторить, потому что переопределение шаблона DefaultTemplateName указывает на этот настраиваемый шаблон, а не на шаблон "TextField". В настраиваемом шаблоне используется тот же самый идентификатор ID, потому что базовый метод CreateChildControls (см. выше) может ссылаться на элемент управления через этот идентификатор.

  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 (Field Types), Элемент FieldType (Field Types) и Элемент Field (Field Types). Обратите внимание, что элемент <Field Name="FieldTypeClass"> должен полностью находиться в одной строке.

  3. Значение элемента <Field Name="FieldTypeClass"> — это полное имя настраиваемого класса полей, за которым следует запятая и маркер Visual Studio 2010 ($SharePoint.Project.AssemblyFullName$). При компиляции проекта создается копия этого файла, в которой маркер заменяется полным именем сборки, состоящим из четырех частей. Эта копия развертывается при выборе команды Развернуть решение в меню Visual Studio ПостроениеVisual Studio 2010. Если Visual Studio 2010 не используется, необходимо скомпилировать проект на этом этапе (даже если проект не завершен), чтобы создать маркер открытого ключа. Чтобы получить полное имя сборки, состоящее из четырех частей, и вставить его вручную вместо маркера, воспользуйтесь средством, описанным в разделе Практическое руководство. Создание инструмента для получения полного имени сборки.

Создание таблицы стилей 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 используется полужирный шрифт.

    Заголовок столбца в режиме представления списка отображается другой таблицей стилей XSLT, которая содержится во встроенном файле fldtypes.xsl в каталоге %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATES\LAYOUTS\XSL.

Построение и тестирование настраиваемого типа поля

Для построения и тестирования настраиваемого типа поля

  1. В меню Построение выберите команду Развернуть. При выборе этой команды автоматически запускается повторное построение сборки, развертывание сборки в глобальном кэше сборок, развертывание 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 и перезапуск веб-приложения.

    ПримечаниеПримечание

    Если развертывание выполняется в ферме серверов, описанные выше действия не выполняются автоматически. Чтобы развернуть решение isbn_field_type.wsp, воспользуйтесь страницей Управление решениями приложения "Центр администрирования" или командлетом SharePoint.

  2. В веб-приложении SharePoint откройте веб-сайт и создайте список с именем "Книги".

  3. Добавьте к этому списку новый столбец. На странице Создать столбец в качестве имени столбца введите "ISBN".

  4. Щелкните переключатель ISBN для книги.

  5. Щелкните переключатель Да, чтобы создать требуемое поле.

  6. Оставьте установленный флажок Добавить в представление по умолчанию.

  7. Нажмите кнопку ОК.

  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 объявляются в файлах MobileDefaultTemplates.ascx и GbwMobileDefaultTemplates.ascx, а не в файлах DefaultTemplates.ascx.

  • Элементы управления прорисовкой мобильных полей имеют свое собственное пространство имен Microsoft.SharePoint.MobileControls, и они происходят от классов в пространстве имен ASP.NET System.Web.UI.MobileControls (а не в пространстве имен System.Web.UI.WebControls).

  • Иерархия наследования для элементов управления прорисовкой мобильных полей несколько отличается от иерархии для элементов управления прорисовкой обычных полей. Например, функции TemplateBasedControl и FormComponent при прорисовке обычных полей объединяются в класс SPMobileComponent.

  • Настраиваемые элементы управления прорисовкой полей, которые создаются для мобильного контекста, в большей степени опираются на метод CreateChildControls, управляющий прорисовкой поля, чем на шаблон прорисовки, по сравнению с настраиваемыми элементами управления прорисовкой полей, создаваемыми для компьютерных браузеров. Более того, при разработке настраиваемых мобильных элементов управления прорисовкой редко переопределяется сам метод CreateChildControls. Вместо этого настраиваемые мобильные элементы управления прорисовкой обычно переопределяют один или более из четырех их методов, вызываемых методом CreateChildControls :

См. также

Ссылка

Элемент FieldTypes (Field Types)

Элемент FieldType (Field Types)

Элемент Field (Field Types)

Namespace Naming Guidelines

Элемент RenderPattern (Field Types)

AlternateTemplateName

BaseValidator

ControlTemplate

CreateChildControls

DefaultAlternateTemplateName

DefaultTemplateName

EnsureChildControls

FieldRenderingControl

GetValidatedString

ItemFieldValue

Label

OnLoad()

RegularExpressions

RenderingTemplate

SPControlMode

SPFieldText

SPFieldValidationException

Template

TemplateName

TextBox

TextField

ValidationRule

Value

Концепции

Инструкции. Создание настраиваемого класса поля

Практическое руководство. Создание определения настраиваемого типа поля

Развертывание типов настраиваемых полей

Проверка данных в настраиваемых полях

Инструкции: создание элемента управления визуализацией поля

Практическое руководство. Создание шаблонов отображения полей

Практическое руководство. Создание настраиваемого типа поля

Обзор решений