понедельник, 18 июля 2011 г.

Статические типы данных (3): Форма для редактирования элементов

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

Нужна форма для редактирования элемента, которую нужно привязать к действиям AddDataAction и EditDataAction.

Форма создается при помощи файла определения формы в XML формате, относительный путь к которому вы затем указываете в атрибуте CustomFormMarkupPath XML-элементов для указанных выше действий. Напр.:

<Actions>
  <AddDataAction Label="Добавить продукт" Type="Samples.IProduct" CustomFormMarkupPath="~/App_Data/Composite/DynamicTypeForms/ProductForm.xml"/>
</Actions>

Самый простой способ быстро создать нужную нам форму - это создать динамический тип данных с  такими же полями, взять файл определения его формы и использовать его для статического типа:
  1. В разделе "Данные" создайте глобальный тип данных с произвольным названием.
  2. Добавьте в него поля с такими же названиями и типами полей, как и в  вашем статического типе данных, но без поля Id (напомню: Name (строка, 64), Description (строка, 1024), Date (DateTime).
  3. Для поля Description, замените виджет с TextBox на TextArea.
  4. Сохраните тип данных.
Создав тип данных, теперь вы можете сгенерировать форму на его основе:
  1. Теперь выберите этот динамический тип данных...
  2. ... и нажмите кнопку "Изменить разметку формы" на панели инструментов.
  3. Сделайте незначительное изменение в открывшемся определении формы (напр, добавьте/удалите пробел где-нибудь между элементами) ...
  4. ... и сохраните ее. Благодаря этому, в папке /App_Data/Composite/DynamicTypeForms/ (в подпапке по имени пространства типа данных) появится нужный вам файл (имя динамического типа данных).
  5. Переименуйте этот файл как вам нужно, напр., ProductForm.xml, ...
  6. ... и переместите его, куда вам нужно, напр., в папку /App_Data/Composite/DynamicTypeForms/.
Второй вариант - это создать форму вручную:
  1. В папке /App_Data/Composite/DynamicTypeForms/ создайте файл определения формы, напр. ProductForm.xml.
  2. Заполните его таким XMLом:

    <cms:formdefinition xmlns:cms="http://www.composite.net/ns/management/bindingforms/1.0" xmlns="http://www.composite.net/ns/management/bindingforms/std.ui.controls.lib/1.0" xmlns:f="http://www.composite.net/ns/management/bindingforms/std.function.lib/1.0">
      <cms:bindings>
        <cms:binding name="Id" type="System.Guid" optional="true" />
        <cms:binding name="Name" type="System.String" optional="true" />
        <cms:binding name="Description" type="System.String" optional="true" />
        <cms:binding name="Date" type="System.DateTime" optional="true" />
      </cms:bindings>
      <cms:layout>
        <cms:layout.label>
          <cms:read source="Name" />
        </cms:layout.label>
        <FieldGroup>
          <TextBox Label="Название" Help="Название продукта">
            <TextBox.Text>
              <cms:bind source="Name" />
            </TextBox.Text>
          </TextBox>
          <TextArea Label="Описание" Help="Кртакое описание продукта">
            <TextArea.Text>
              <cms:bind source="Description" />
            </TextArea.Text>
          </TextArea>
          <DateSelector Label="Дата" Help="Дата добавления продукта в каталог">
            <DateSelector.Date>
              <cms:bind source="Date" />
            </DateSelector.Date>
          </DateSelector>
        </FieldGroup>
      </cms:layout>
    </cms:formdefinition>

  3. Сохраните файл.
А теперь привяжите этот файл к действиям в файле определения дерева:
  1. В папке \App_Data\Composite\TreeDefinitions\, откройте файл нашего определения дерева: ProductView.xml.
  2. Найдите XML-элементы AddDataAction и EditDataAction.
  3. Добавьте в каждый из них атрибут CustomFormMarkupPath ...
  4. ... и укажите в нем путь к вашей форме, напр. "/App_Data/Composite/DynamicTypeForms/ProductForm.xml".
  5. Сохраните файл.
Теперь ваш файл определения будет теперь выглядеть примерно так:

<?xml version="1.0" encoding="utf-8" ?>
<ElementStructure xmlns="http://www.composite.net/ns/management/trees/treemarkup/1.0">
  <ElementStructure.AutoAttachments>
    <NamedParent Name="Data" Position="Top"/>
  </ElementStructure.AutoAttachments>
  <ElementRoot>
    <Children>
      <Element Id="ProductsRoot" Label="Продукты">
        <Actions>
          <AddDataAction Label="Добавить продукт" Type="Samples.IProduct" CustomFormMarkupPath="~/App_Data/Composite/DynamicTypeForms/ProductForm.xml"/>
        </Actions>
        <Children>
          <DataElements Type="Samples.IProduct" Label="${C1:Data:Samples.IProduct:Name}">
            <Actions>
              <EditDataAction Label="Изменить продукт" CustomFormMarkupPath="~/App_Data/Composite/DynamicTypeForms/ProductForm.xml"/>
              <DeleteDataAction Label="Удалить продукт"/>
            </Actions>
            <OrderBy>
              <Field FieldName="Name" Direction="ascending"/>
            </OrderBy>
          </DataElements>
        </Children>
      </Element>
    </Children>
  </ElementRoot>
</ElementStructure>

В результате вы сможете добавлять и изменять элементы статического типа Samples.IProduct.


Если ваш статический тип данных - более "продвинутый" (в нем больше разнотипных полей и т.п.), вам, вероятно, понадобится и более продвинутая форма, напр., группирующая поля по разделам и вкладках и т.п.

Для этого вам нужно разбираться в синтаксисе, использующимся в определении форм данных в C1. Об этом можно почитать в "Form Markup" (англ.). А в одном из следующих сообщений я остановлюсь на этом более подробно. 

3 комментария:

  1. Добрый день.
    А можно ли получить доступ к данным, статического типа из XSLT функций? При создании данных динамичкского типа (из консоли) автоматически появляются связанные с ними функции типа GetXml и т.п. Или нужно использовать внешние С# функции? Если так, то можно ли вызывать внешние C# функции из XSLT функций?

    ОтветитьУдалить
  2. См. http://compositec1.codeplex.com/discussions/437941#post1021104 (англ.)

    ОтветитьУдалить