Расширяем возможности SharePoint ListFieldIterator

Введение

Если вы занимаетесь разработкой под SharePoint, то наверняка вам знаком этот элемент управления (ListFieldIterator). В настоящее время передо мной стоит задача, решение которой я решил провести через расширение стандартных возможностей данного контрола.

Если же вы не совсем понимаете о чём идёт речь, то я готов рассказать о ListFieldIterator

Этот контрол предназначен для отображения атрибутов ваших записей для чтения и редактирования на формах:

image

Насколько известно, отображение записей (я имею ввиду под “запись” SPListItem) регулируется с помощью списка (SPList), либо типа содержимого (SPContentType), для этого необходимо указать в свойствах DisplayFormTemplateName, EditFormTemplateName, NewFormTemplateName наименование необходимого шаблона. Сам же шаблон должен находится в файле: 12\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx

Описание стандартного шаблона выглядит следующим образом:

<SharePoint:RenderingTemplate ID="ListForm" runat="server"> 
  <Template> 
    <span id='part1'> 
      <SharePoint:InformationBar ID="InformationBar2" runat="server" /> 
      <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator="&nbsp;" 
        runat="server"> 
        <template_rightbuttons> 
                        <SharePoint:NextPageButton runat="server"/> 
                        <SharePoint:SaveButton runat="server"/> 
                        <SharePoint:GoBackButton runat="server"/> 
                    </template_rightbuttons> 
      </wssuc:ToolBar> 
      <SharePoint:FormToolBar ID="FormToolBar2" runat="server" /> 
      <table class="ms-formtable" style="margin-top: 8px;" border="0" cellpadding="0" cellspacing="0" 
        width="100%"> 
        <SharePoint:ChangeContentType ID="ChangeContentType2" runat="server" /> 
        <SharePoint:FolderFormFields ID="FolderFormFields2" runat="server" /> 
        <SharePoint:ListFieldIterator ID="ListFieldIterator2" runat="server" /> 
        <SharePoint:ApprovalStatus ID="ApprovalStatus2" runat="server" /> 
        <SharePoint:FormComponent ID="FormComponent2" TemplateName="AttachmentRows" runat="server" /> 
      </table> 
      <table cellpadding="0" cellspacing="0" width="100%"> 
        <tr> 
          <td class="ms-formline"> 
            <img src="/_layouts/images/blank.gif" width="1" height="1" alt=""> 
          </td> 
        </tr> 
      </table> 
      <table cellpadding="0" cellspacing="0" width="100%" style="padding-top: 7px"> 
        <tr> 
          <td width="100%"> 
            <SharePoint:ItemHiddenVersion ID="ItemHiddenVersion2" runat="server" /> 
            <SharePoint:ParentInformationField ID="ParentInformationField2" runat="server" /> 
            <SharePoint:InitContentType ID="InitContentType2" runat="server" /> 
            <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator="&nbsp;" 
              runat="server"> 
              <template_buttons> 
                        <SharePoint:CreatedModifiedInfo runat="server"/> 
                    </template_buttons> 
              <template_rightbuttons> 
                        <SharePoint:SaveButton runat="server"/> 
                        <SharePoint:GoBackButton runat="server"/> 
                    </template_rightbuttons> 
            </wssuc:ToolBar> 
          </td> 
        </tr> 
      </table> 
    </span> 
    <SharePoint:AttachmentUpload ID="AttachmentUpload2" runat="server" /> 
  </Template> 
</SharePoint:RenderingTemplate>

Этот шаблон, под названием “ListForm”, используется всеми стандартными списками по-умолчанию. Как не трудно заметить в данном шаблоне как раз и описан элемент управления ListFieldIterator.

Первоначально продемонстрирую результат, который мы получим по завершению данной статьи:

image

Итак, приступим к изменению представления карточки, чтобы получить возможности:

  • Разделения полей на области, что порой востребовано
  • Регулирование отображения количества полей в строке
  • Регулирование правил отображения полей в зависимости от состояния и текущего пользователя

Во-первых создадим свой класс, в моём случае это будет FieldSetFieldIterator:

 
public class FieldSetFieldIterator : ListFieldIterator
{}

Воспользовавшись рефлектором и предварительно ознакомившись в ListFieldIterator’ом я пришёл к выводу, что основная логика формирования шаблнов представления полей для их последующего вывода основана на коллекции доступных полей

 
SPContext.Current.FormContext.FieldControlCollection

а так же на методе, обрабатывающем свойство ExcludeFields. Это свойство предназначено для регулирования, какие поля не следует отображать

 
protected override bool IsFieldExcluded(Microsoft.SharePoint.SPField field)
{
    return base.IsFieldExcluded(field);
}

Не трудно догадаться, что переопределение данного метода мне так же импонирует.

Самая сложная часть реализации нашего контрола – переопределение логики представления, а именно метода

 
protected override void Render(HtmlTextWriter output)
{
    foreach (var fieldSet in fieldSets)
    {
       GenerateTableStart(fieldSet, output);
       GenerateTableBody(fieldSet, configurationFieldsSets.Rows, output);
       GenerateTableEnd(fieldSet, output);
     } 
}

Для каждого из FieldSet’ов (это условное название для обозначения регионов отображения полей, по мотивам HTML FieldSet) рисуется табличка, котрое в последствии заполняется описанными в конфигурационном файле полями в соответствующих состояниях.

Состояние поля, так же как и состояние страницы определяется перечислением:

 
public enum SPControlMode
{
    Invalid,
    Display,
    Edit,
    New
}

Соответственно, в наших силах получив элемент BaseFieldControl для текущего поля, изменить его состояние на необходимое нам.

Конфигурирование элемента

Конфигурация данного контрола реализуется через интерфейс, соответственно даёт гибкость в реализации

 
public interface IFieldSetConfigurator : IFieldConfigurator
{
  FieldsConfiguration FieldsConfiguration { get; }
}

В настоящее время конфигурационные данные будут хранится в описании типа содержимого в разделе XmlDocuments

 

<XmlDocuments>
  <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
    <FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
      <Display>FieldSetListForm</Display>
      <Edit>FieldSetListForm</Edit>
      <New>FieldSetListForm</New>
    </FormTemplates>
    <Configuration>
      <FieldsConfiguration>
        <FieldsSets Rows='3'>
          <FieldSet Name='Основные'>
            <Field InternalName='Title' />
            <Field InternalName='StartDate' DisableForUsers='domain/user1'/>
            <Field InternalName='Author' />
            <Field InternalName='_ModerationComments' />
            <Field InternalName='Gender' />
            <Field InternalName='PercentComplete' />
            <Field InternalName='URL' />
          </FieldSet>
          <FieldSet Name='Дополнительные'>
            <Field InternalName='Editor' />
            <Field InternalName='WorkFax' />
          </FieldSet>
        </FieldsSets>
      </FieldsConfiguration>
    </Configuration>
  </XmlDocument>
</XmlDocuments>

Кстати, стоит обратить внимание на переопределенные для типа содержимого формы на те, в которых будет описан наш элемент управления.

Стоит так же не забыть, что при переопределении ListFieldIterator’а, при работе с вложениями будет нарушено единообразие формы, т.е. этот элемент так же необходимо переопределить:

 
 public class FieldSetFormComponent : FormComponent
  {
    public const string AttachmentTemplateName = "AttachmentRows";
    public const string AttachmentsFieldName = "Attachments";

    /// <exception cref="ArgumentException">TemplateName</exception>
    protected override void CreateChildControls()
    {
      if (TemplateName != AttachmentTemplateName)
        throw new ArgumentException("TemplateName");
      //…
    }
  }

Здесь необходимо обратить внимание на то, что столбец для вложений отображается с помощью шаблона, основанного на FormComponent c определенным названием “AttachmentRows”, его и необходимо переопределить.

Спасибо за внимание. В данной статье мы немного разобрались с механизмами представления данных в списках SharePoint, а так же убедились в непринужденной легкости расширения логики отображения.

Advertisements

2 комментария on “Расширяем возможности SharePoint ListFieldIterator”

  1. Хотел добавить чтоВы можете заменять не только сам шаблон, но и саму страницу, которая используется при создании списка путем объединения шаблона страницы и самого шаблона отображения элемента списка или библиотеки

  2. DkmS:

    А вот здесь просто пишется html-шаблон: http://dyakov.design.officelive.com/directpsi.aspx


Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s