Создание собственных типов полей (custom field)

 Комментарии можно оставлять "здесь"

Случается такая необходимость, когда стандартных типов полей (таких как строки, числа, подстановка и другие)недостаточно, создать собственный тип поля для специфичной или удобной установки значений в поле. Например, если нужно брать значения из списков другого сайта или даже семейства сайтов с отображением в виде дерева или с фильтрацией.
 Данную проблему можно решить разработкой собственного типа поля, который в дальнейшем администраторы могут использовать в любом списке.
 Рассмотрим пример создания собственного типа поля, который в режиме редактирования и создания будет отображаться в виде выпадающего списка. Значения списка для простоты будут константами, но задаваться программно. Соответственно ничто не мешает в дальнейшем в этом месте динамически подставлять значения из различных хранилищ.
  Так что нам предстоит сделать
  • Создать шаблон поля. А именно пользовательский элемент управления, который будет отвечать за интерфейс
  • Создать класс, отвечающий за логику поведения нового типа поля. Новый класс будет наследоваться от какого-нибудь стандартного
  • "Сообщить" SharePoint-у о появлении нового типа поля
1. Добавим в наш проект сопоставляемые папки: CONTROLTEMPLATES и XML.
В первой папке будем создавать шаблон, а во второй - файл, описывающий наше поле.
2. Добавим пользовательский элемент управления с именем CustomField.ascx.
Необходимое содержимое файла:
<%@ 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" %>
<%@ Control Language="C#" AutoEventWireup="true" %>
<SharePoint:RenderingTemplate ID="CustomField" runat="server"%>
 <Template>
  <fieldset>
   <legend>Выбор значения</legend>
   <asp:Label ID="lb1" runat="server"></asp:Label>
   <asp:Label ID="lb2" runat="server"></asp:Label>
   <asp:DropDownList ID="ddlFieldValue" runat="server"></asp:DropDownList>
  </fieldset>
 </Template>
</SharePoint:RenderingTemplate>
3. Создадим класс CustomFieldClass.cs, описывающий логику поля.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Demo
{
 // Наш тип поля наследуется от стандартного текстового
 public class CustomFieldClass : SPFieldText
 {
  public override BaseFieldControl FieldRenderingControl
  {
   get
   {
    // Возвращается класс, работающий с шаблоном поля
    FieldView ov = new FieldView() { FieldName = base.InternalName };
    return ov;
   }
  }

  public CustomFieldClass(SPFieldCollection fields, string fieldName)
      : base(fields, fieldName)
  {
  }

  public CustomFieldClass(SPFieldCollection fields, string typeName, string displayName)
      : base(fields, typeName, displayName)
  {
  }
 }

 // Сам класс работы с шаблоном
 public class FieldView : BaseFieldControl
 {
  protected override string DefaultTemplateName
  {
   get
   {
    // Возвращает имя шаблона, в нашем случаи описанный в файле CustomField.ascx
    return "CustomField";
   }
  }

  // Получение значения поля при сохранении
  public override object Value
  {
   get
   {
    EnsureChildControls();
    DropDownList ddl = TemplateContainer.FindControl("ddlFieldValue") as DropDownList;
    Label lb1 = TemplateContainer.FindControl("lb1") as Label;
    Label lb2 = TemplateContainer.FindControl("lb2") as Label;

    var value = ddl.SelectedItem;
    return value.Value;
   }
   set
   {
    EnsureChildControls();
   }
  }
  // Внесение данных в шаблон
  protected override void CreateChildControls()
  {
   base.CreateChildControls();
   if (this.ControlMode != SPControlMode.Display)
   {
    // Поиск необходимых контролов
    DropDownList ddl = TemplateContainer.FindControl("ddlFieldValue") as DropDownList;
    Label lb1 = TemplateContainer.FindControl("lb1") as Label;
    Label lb2 = TemplateContainer.FindControl("lb2") as Label;

    CustomFieldClass curItem = this.Field as CustomFieldClass;

    if (!Page.IsPostBack)
    {
     // Добавление значений в контролы
     lb1.Text = "Заголовок 1";
     ddl.Items.Add(new ListItem() { Text = "Значение1", Value = "Значение1" });
     ddl.Items.Add(new ListItem() { Text = "Значение2", Value = "Значение2" });
     ddl.Items.Add(new ListItem() { Text = "Значение3", Value = "Значение3" });
     ddl.Items.Add(new ListItem() { Text = "Значение4", Value = "Значение4" });
    }
   }
  }
 }
}
4. В папке XML создадим файл FLDTYPES_CustomField.XML , который будет описывать наш новый тип поля
<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
 <FieldType>
  <Field Name="TypeName">CustomFieldClass</Field>
  <Field Name="ParentType">Text</Field>
  <Field Name="TypeDisplayName">Собственное поле</Field>
  <Field Name="TypeShortDescription">Собственное поле</Field>
  <Field Name="FieldTypeClass">Demo.CustomFieldClass,$SharePoint.Project.AssemblyFullName$</Field>
 </FieldType>
</FieldTypes>
5. После развёртывания к спискам можно добавить столбец с нашим типом
6. Теперь этот тип можно использовать и при создании своего типа контента 
<Field Type="CustomFieldClass" DisplayName="Моё поле" ID="{F92BDF04-8D85-4F78-8E75-1CF3EA0EC694}" StaticName="curFiels" Name="curFiels" Group="_Группа" />

 Комментарии можно оставлять "здесь"

Комментариев нет:

Яндекс.Метрика