none
SharePoint 2013. Проблема с разверткой кастомной формы списка (custom list form).

    Вопрос

  • Продолжаю создавать кастомные формы для своих списков (SP 2013). Методика следующая:

    - в проекте VS создается Application page. Данная страница развертывается, например в Site Pages при помощи модуля.

    - в схеме списка прописываю путь к этой странице: <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="features\SitePages_pv_SitePages\ListsForms\pvDispFormContracts.aspx"  WebPartZoneID="Main" /> - тут я просто изменяю значение атрибута SetupPath, все остальное не меняется. Развертываем список.

    - в SPD редактирую форму нужного типа до приемлемого вида.

    - заголовки страницу aspx в студии корректирую, чтобы она могла работать с веб-частями: добавляю регистрацию WebPartPages, меняю DynamicMasterPage на MasterPage. Больше никаких значимых изменений. Далее заменяю ее контекст разметкой из формы, которую редактировал в SPD. Развертываем... и получаем непонятно что.

    Если верить SPD, то разметка меняется: появляется дополнительная веб-часть ListFormWebPart того же списка, несмотря на то, что она уже присутствует в разметке. Причем фиксированного места ее появления нет. Пропадает веб-часть подчиненного списка:

    Visual Stido: ListFormWebPart (элемент главного списка), XsltListFormWebPart (подчиненный список) - оригинал, все как надо.

    Далее в SPD смотрим что у нас задеплоилось в SitePages (pvDispFormContracts.aspx): только ListFormWebPart. Все! spd больше ничего не показывает.

    Смотрим через SPD какая форма у нас в каталоге списка (DispForm.aspx): ListFormWebPart, ListFormWebPart. Больше ничего не видим... Почему?

    Открываем элемент списка на просмотр: ListFormWebPart, ListFormWebPert, XsltListViewWebPart. Откуда!!! Если ее не видно было до этого нигде.

    Это итоговый вариант - зеленым выделены веб части из оригинала. Красным - та самая веб-часть, которая появляется, начиная с DisplayForm.aspx (созданная на основании нашей страницы форма), ее быть не должно.

    1. Почему так странно себя ведет SPD - почему при просмотре форм в нем меняется разметка.

    2. Откуда берется дополнительная веб часть?

    Отвечу на любые уточняющие вопросы ибо понимаю, что поверить и понять написанное не просто :). Я старался как мог описать свои действия и результаты.

    14 февраля 2017 г. 14:46

Ответы

  • Грубо говоря план сработал Page_Load() application page:

                SPWeb web = SPContext.Current.Web;

                bool old_AllowUnsafeUpdates = web.AllowUnsafeUpdates;
                web.AllowUnsafeUpdates = true;

                SPLimitedWebPartManager wpM = web.GetLimitedWebPartManager(Request.CurrentExecutionFilePath, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);

                // добавляем Акты
                XsltListViewWebPart wp = new XsltListViewWebPart();
                wp.Title = "Акты";
                wp.ListId = new Guid("1f98a2e5-1b29-4ee8-8d58-6be0070fe12c");
                //
                wpM.AddWebPart(wp, "WPZ_acts", 0);

                // добавляем Дополнительные соглашения
                XsltListViewWebPart wp2 = new XsltListViewWebPart();
                wp2.Title = "Дополнительные соглашения";
                wp2.ListId = new Guid("56438406-b4fb-4041-ad8e-82631832bf11");
                //
                wpM.AddWebPart(wp2, "WPZ_ageements", 0);
                //
                web.AllowUnsafeUpdates = old_AllowUnsafeUpdates;

    Все появляется на своих местах. Правда пока это реализовано в коде самой страницы, поэтому количество веб-частей при каждом ее открытии растет. Идеально это надо реализовывать в обработчиках фичи по установке формы... наверное это фича, которая разворачивает список.

    У кого будут какие замечания или предложения, буду рад прочитать. Все-таки остался открытым вопрос о том, что есть "черный ящик" и как с ним работать?


    • Изменено Denis Prokofjev 15 февраля 2017 г. 13:34
    • Помечено в качестве ответа Denis Prokofjev 15 февраля 2017 г. 13:34
    15 февраля 2017 г. 13:34

Все ответы

  • Кое-что проясняется. Для себя этот процесс определил как: Application page - "Черный ящик" - DisplayForm. Не знаю, кто и что стоит за черным ящиком, но в результате его работы страница преображалась для меня непредсказуемо. Поэтому решил сделать так:

    1. Т.к. в ListDefinition у нас при объявлении формы указана веб-зона Main, решил ее оставить в покое. Просто ее очистил.

    2. Создал отдельно свои веб-зоны и в одной из них оставил XsltListViewWebPart.

    3. Добавил пространство имен своей Application Page в коллекцию Safe Controls модуля, который деплоит эту страницу.

    Что получилось: Предсказуемое появление ListFormWebPart в зоне Main. Она идеально в нее вписывается, как и должно быть. Далее - дополнительную веб-часть (XsltLVWP) я не вижу - все-таки "черный ящик" вычищает все веб-зоны при создании DisplayForm.aspx. Но главное - я получил доступ к серверному коду. Я могу создавать контролы, обрабатывать их события (например Click кнопки), получил доступ ко всем свойствам страницы.

    Нашел упоминание объекта LimitedWebPartManager (http://sharepoint.stackexchange.com/questions/9442/how-to-programmatically-add-a-webpart-to-a-page) - да я получаю доступ к веб-зонам и веб-частям своей страницы.

    Является ли это правильным путем? Корректно ли с т.з. SP добавление веб-частей при загрузке страницы (Page_Load()) формы элемента списка? Ну и создание между ними связей?

    Подскажите, что мне делать дальше? Может пример с добавлением в мою форму представления списка и установки фильтра в нем по ID текущего элемента (значения тек. элемента я видел в свойствах веб-части LFWP - это вроде бы не проблема).


    15 февраля 2017 г. 12:47
  • Грубо говоря план сработал Page_Load() application page:

                SPWeb web = SPContext.Current.Web;

                bool old_AllowUnsafeUpdates = web.AllowUnsafeUpdates;
                web.AllowUnsafeUpdates = true;

                SPLimitedWebPartManager wpM = web.GetLimitedWebPartManager(Request.CurrentExecutionFilePath, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);

                // добавляем Акты
                XsltListViewWebPart wp = new XsltListViewWebPart();
                wp.Title = "Акты";
                wp.ListId = new Guid("1f98a2e5-1b29-4ee8-8d58-6be0070fe12c");
                //
                wpM.AddWebPart(wp, "WPZ_acts", 0);

                // добавляем Дополнительные соглашения
                XsltListViewWebPart wp2 = new XsltListViewWebPart();
                wp2.Title = "Дополнительные соглашения";
                wp2.ListId = new Guid("56438406-b4fb-4041-ad8e-82631832bf11");
                //
                wpM.AddWebPart(wp2, "WPZ_ageements", 0);
                //
                web.AllowUnsafeUpdates = old_AllowUnsafeUpdates;

    Все появляется на своих местах. Правда пока это реализовано в коде самой страницы, поэтому количество веб-частей при каждом ее открытии растет. Идеально это надо реализовывать в обработчиках фичи по установке формы... наверное это фича, которая разворачивает список.

    У кого будут какие замечания или предложения, буду рад прочитать. Все-таки остался открытым вопрос о том, что есть "черный ящик" и как с ним работать?


    • Изменено Denis Prokofjev 15 февраля 2017 г. 13:34
    • Помечено в качестве ответа Denis Prokofjev 15 февраля 2017 г. 13:34
    15 февраля 2017 г. 13:34
  • У меня еще такой вопрос. Как программно "повторить" строчку: <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="features\SitePages_pv_SitePages\ListsForms\ContractsDispForm.aspx"  WebPartZoneID="Main" /> ?

    Это строка из схемы списка из раздела Forms. Она на основе страницы aspx создает форму списка. Как оказалось, при более сложных манипуляциях с веб-частями в форме элемента может пропадать стандартный хром. Поэтому мне необходимо при возможности "пересоздавать" форму заново. Это автоматически делается при развертке списка, но этот вариант плох, т.к. при нем теряются все данные списка как минимум.

    В общем, интересует именно, как "повторить действия" этой строки в точности, как при первоначальном создании списка?

    Знаком со статьей: https://platinumdogs.me/2011/12/23/sharepoint-2010-create-and-update-list-forms-programmatically/ , но данная методика подразумевает редактирование свойств типа контента, прописываем Url уже существующей кастомной формы. Этот вариант мне не подходит - моя страница не является формой или шаблоном в полном смысле этих значений.

    Итак, как программно реализовать: <Forms> ... <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="features\SitePages_pv_SitePages\ListsForms\ContractsDispForm.aspx"  WebPartZoneID="Main" /> .. </Forms> ?


    17 февраля 2017 г. 12:30