Блог Сергея Байдачного

Мой блог о технологиях

Archive for Март 2010

Windows Phone series 7 free ebook

leave a comment »

Written by Sergiy Baydachnyy

30.03.2010 at 09:49

Опубликовано в Microsoft

Tagged with

SharePoint 2010: Очень большой пост о Ленте (Ribbon)

8 комментариев

Сел вчера раскрыть тему Лента. Получилось 8 страниц … и это еще не все. В книге будет больше (о JavaScript и зависимых закладках). Хочу убить тех, кто писал документацию.

Итак,

 

Начнем с первого, что, вероятнее всего, сразу бросится в глаза – Лента (Ribbon). Элемент управления Лента впервые появился в приложениях Microsoft Office 2007 и теперь перекочевал в SharePoint. Фактически везде, где требуется меню, управляющее контентом (как сайта, так и списками), возникает Лента.

 

@1.1

@1.1 Элемент управления Лента

 

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

 

@1.2

@1.2 Изменение размеров элементов в Ленте

 

Для разработчика наличие ленты означает, что необходимо изучить механизмы настройки Ленты и подключения новой функциональности. Давайте рассмотрим этот вопрос более подробно.

Начнем с описания стандартной Ленты, которая уже присутствует в SharePoint и описывается с помощью XML. Исходный файл Вы сможете найти в следующем каталоге: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL\XML в файле CMDUI.xml. К сожалению, описание элемента Лента пока не представлено достаточно полно в SDK, поэтому этот файл может служить для Вас хорошим примером создания групп и закладок.

На данном этапе нужно обратить на то, что все элементы в этом файле имеют атрибут ID, который очень пригодиться при выполнении настройки Ленты. Так, если Вы решите удалить или заменить одну из кнопок, то Вам потребуется ID этой кнопки, так же как и ID группы при добавлении новой кнопки. Список всех ID можно найти в SDK, но я предпочитаю пользоваться этим файлом. Также нужно отметить, что при формировании ID элемента используют нотацию, позволяющую точно указать расположение элемента или группы, комбинируя имя родительского элемента и новое имя с разделением их точкой. Так ID со значением Ribbon.WikiPageTab.Manage.PageProperties, позволяет однозначно сказать, что речь идет о группе Manage на закладке Page.

Естественно, что основное наполнение Ленты образуют элементарные элементы. Так в CMDUI.xml можно найти следующие элементы, которые полностью покрывают весь список доступных элементов в Ленте:

· Button – обычная кнопка, которая отображается на Ленте в виде изображения размером 32 на 32 пикселя или 16 на 16 пикселей;

· CheckBox – стандартный элемент, реализующий работу переключателя;

· ColorPicker – этот элемент управления представляет собой таблицу, позволяющую выбрать цвет;

· ComboBox – позволяет реализовать выбор одного из предопределенных значений с использованием мыши или путем ввода значения с клавиатуры;

· DropDown – элемент, аналогичный ComboBox, но не поддерживающий ввод с клавиатуры;

· FlyoutAnchor – специальная кнопка, позволяющая открыть выпадающее окно, содержащее другие элементы. Подобные кнопки можно увидеть даже на обычной закладке Page при редактировании текста. Вы можете заметить эту кнопку, устанавливая цвет шрифта или фона;

· InsertTable – применимость этого элемента небольшая. Фактически он используется только в текстовых редакторах, позволяющих вставить таблицу – позволяет в отображаемом гриде быстро выбрать число строк и столбцов будущей таблицы;

· Label – определяет надпись;

· Menu – специальный элемент управления, позволяющий отобразить всплывающее меню. Обычно используется вместе с SplitButton и FlyoutAnchor;

· MenuSection – этот элемент используется совместно с Menu, позволяя разделить меню на отдельные секции;

· MRUSplitButton – очень напоминает SplitButton, но в отличии от последней, может использовать в качестве команды основной кнопки один из пунктов выпадающего меню, который может меняться динамически. Примером может служить кнопка Edit на закладке Page, которая после нажатия преобразуется в кнопку Save;

· Spinner – может использоваться для ввода значения или выбора одного из значений из списка. Примером может служить элемент, позволяющий выбрать размер текста – размеры представлены не все, но это не мешает ввести произвольный размер и применить его для выделенного текста;

· SplitButton – этот элемент управления используется сразу как кнопка и меню, отображая изображение и курсор, позволяющий перейти к выпадающему меню. Если пользователь щелкает на изображении, то выполняется действие по умолчанию, а если на курсоре, то пользователь переходит на выпадающее меню;

· TextBox – определяет текстовое поле;

· ToggleButton – обычная кнопка, которая может оставаться в нажатом состоянии до следующего клика.

В качестве примера описания одного из элементов можно рассмотреть простейший элемент Button:

<Button
 Id="Ribbon.DocLibListForm.Edit.Clipboard.Paste"
 Sequence="10"
 Command="Ribbon.ListForm.Edit.Clipboard.Paste" 
 Image16by16=
    "/_layouts/$Resources:core,Language;/images/formatmap16x16.png?vk=4536" 
 Image16by16Top="-176" Image16by16Left="-112"
 Image32by32=
    "/_layouts/$Resources:core,Language;/images/formatmap32x32.png?vk=4536"   
 Image32by32Top="-32" Image32by32Left="-160"
 LabelText="$Resources:core,ButPasteMenu;"
 ToolTipTitle="$Resources:core,ButPasteMenu;"
 ToolTipDescription="$Resources:core,cui_STT_ButPasteMenu;"
 TemplateAlias="o1"/>

 

Как видно, тут определяются параметры изображений, всплывающая подсказка, ID, а также атрибут Command, который задает имя команды. Команда назначается динамически или задается при описании Ленты. Атрибут Sequence задает порядковый номер кнопки. Номер умножается на 10, поэтому первая кнопка имеет номер 10. Это сделано для того, чтобы программист мог легко вставить свои кнопки (элементы) в любое место группы элементов. При нумерации закладок сохраняется аналогичный подход, но номер закладки умножается на 100.

Естественно, чтобы задать описание Ленты, одних элементов управления недостаточно. Ведь Лента имеет сложную структуру, разделяя все элементы на отдельные закладки, каждая из которых состоит из нескольких групп. Поэтому следующий набор элементов, которые мы рассмотрим, это элементы-контейнеры, а также элементы, позволяющие задавать шаблоны и способ отображения. Вот список этих элементов:

· Ribbon – элемент, описывающий всю Ленту. Вам не придется его использовать, так как переписывать всю Ленту с нуля не имеет смысла;

· Tabs – определяет контейнер для закладок на Ленте;

· Tab – определяет отдельную закладку на Ленте;

· Groups – является контейнером для групп элементов на отдельной закладке;

· Group – позволяет определить группу конкретных элементов. Является контейнером, в котором и происходит основная работа;

· Controls – является контейнером для набора элементов управления, которые обычно наполняют группу;

· ContextualTabs – представляет собой контейнер в котором собраны все элементы типа ContextualGroup;

· ContextualGroup – определяет закладку, которая будет появляться в зависимости от текущего контекста, связанного с действиями пользователя. Например, при редактировании страницы пользователь переходит на таблицу и получает отдельную закладку для работы с таблицей. Фактически этот элемент содержит такой контейнер как Tab и служит лишь оболочкой;

· Gallery – служит для отображения галерей стилей, шрифтов и др. В SharePoint 2010 применение галерей по умолчанию отсутствует. Но увидеть эти элементы Вы можете в приложениях Office 2010 (2007). Например, галерея используется для отображения списка готовых стилей для шрифта в Word 2010;

· GalleryButton – используется для отображения элемента в галерее;

· GroupTemplate – определяет способ отображения элементов внутри группы. Так, одну из кнопок Вы можете отобразить, используя изображение 16 на 16, а другую – 32 на 32. При этом Вы четко можете указать, какая кнопка будет находиться в верхней позиции, а какая под ней (если речь идет о кнопках 16 на 16);

· MaxSize – устанавливает размеры у заданной группы, ссылаясь на определенный шаблон с помощью GroupTemplate;

· QAT – определяет контейнер для кнопок в панели быстрого доступа, которая находится сразу над Лентой между закладками и меню Site Actions;

· Scale – определяет поведение группы при изменении размеров Ленты;

· Scaling – является контейнером для элементов MaxSize и Scale.

Чтобы лучше понять назначение описанных выше элементов, рассмотрим пример, где выполним модификацию настроек Ленты по умолчанию.

Чтобы приступить к модификации стандартной ленты, используется элемент CustomAction. Если Вы работали с WSS 3.0, то наверняка сталкивались с этим элементом при расширении меню Site Actions, контекстном меню списков и др. Так, следующий синтаксис для CustomAction добавляет новый элемент с заголовком «Go to Microsoft.com» в меню Site Actions:

<CustomAction
  Id="SiteSettings.GoToMicrosoft" 
  Description="This is link to Mocrosoft.com" 
  Title="Go To Microsoft.com" 
  Location="Microsoft.SharePoint.StandardMenu"
  GroupId="SiteActions"
  Sequence="1001" 
  ImageUrl="/_layouts/images/DWSHOME.png">
     <UrlAction Url="http://www.microsoft.com"/>
</CustomAction>

 

Расширим синтаксис элемента CustomAction, добавив изменения в существующую Ленту. Но, прежде чем переходить к коду, рассмотрим, какие предварительные действия нужно выполнить в Visual Studio 2010, чтобы посмотреть пример в действии.

О Visual Studio 2010 мы будем говорить чуть позже, а сейчас просто создадим проект на основе шаблона Empty SharePoint Project. На этом этапе мы получим диалоговое окно, предлагающее создать решение в «песочнице». Чтобы избежать возможных проблем на этом этапе, выберем Deploy as a farm Solution. О песочнице мы будем говорить в одном из следующих разделов.

@1.3

@1.3 Выбор способа развертывания Решения

Созданный проект полностью готов к развертыванию в SharePoint 2010, но не содержит ни одного компонента, расширяющего функциональность SharePoint. Поэтому, чтобы приступить к работе над Лентой, добавим в проект новый элемент на основе шаблона Empty Element. С помощью этого шаблона, мы добавим в проект единицу развертывания SharePoint – Фичу (Feature) или Возможность. Именно с помощью Фич выполняется развертывание любых компонент в SharePoint.

В результате последнего действия было создано несколько файлов, один из которых Elements.xml. Именно с этим файлом мы и будем работать. Так, если внутрь этого файла, поместить приведенный выше код (размещайте код прямо внутрь элемента Elements) и выполнить команду Build->Deploy, то меню Site Actions пополнится еще одной кнопкой.

@1.4

@1.4 Расширение Site Actions

Если все работает, перейдем к модификации CustomAction. Первым делом определим сам CustomAction следующим образом:

<CustomAction
  Id="MyActions.Ribbon.CustomButtons" 
  Location="CommandUI.Ribbon">
 
</CustomAction>

 

Основным параметром тут является Location. Дело в том, что SharePoint подгружает разные версии Ленты, в зависимости от ситуации. Фактически можно выделить 5 различных лент, ID которых можно использовать в атрибуте Location:

· CommandUI.Ribbon – изменения отображаются на основной Ленте. При этом область видимости изменений можно ограничить с помощью RegistrationId и RegistrationType. Если указать значение List для RegistrationType, а в качестве RegistrationId взять 101, то изменения будут видны только при работе с библиотеками документов, определяемых этим номером;

· CommandUI.Ribbon.ListView – изменения применимы для тех документов, где присутствует веб-часть, отображающая данные из списка (ListViewWebPart);

· CommandUI.Ribbon.NewForm – изменения коснутся Ленты, отображаемой в диалоговом окне создания элемента;

· CommandUI.Ribbon.EditForm – изменения коснутся Ленты, отображаемой в диалоговом окне редактирования элемента;

· CommandUI.Ribbon.DisplayForm – изменения коснутся Ленты, отображаемой в диалоговом окне отображения элемента;

В нашем примере мы модифицируем основную Ленту, делая изменения видимыми везде.

Следующим шагом, начнем вносить изменения в отображения кнопок. Так, следующий код удаляет кнопки Edit Properties, Rename Page, и делает изменения с кнопкой Make Home Page, меняя ее заголовок на Go To Microsoft.com:

Замечание!!! Если Вы реализовали код, а изменения в Ленте не наблюдаются, то очистите кэш браузера. Особенно это относится к закладке Page.

<CustomAction
  Id="MyActions.Ribbon.CustomButtons"
  Location="CommandUI.Ribbon">
  <CommandUIExtension>
    <CommandUIDefinitions>
      <CommandUIDefinition 
        Location="Ribbon.WikiPageTab.Manage.PageProperties">
      </CommandUIDefinition>
      <CommandUIDefinition
        Location="Ribbon.WikiPageTab.Manage.RenamePage">
      </CommandUIDefinition>
      <CommandUIDefinition
        Location="Ribbon.WikiPageTab.PageActions.SetHomePage">
        <Button
          Id="Ribbon.WebPartPage.Actions.MakeHomePage"
          Sequence="20"
          Command="makeHomePageMS"
          Image16by16=
         "/_layouts/$Resources:core,Language;/images/formatmap16x16.png?vk=4536" 
          Image16by16Top="-200" 
          Image16by16Left="-32"
          Image32by32=
         "/_layouts/$Resources:core,Language;/images/formatmap32x32.png?vk=4536" 
          Image32by32Top="-128" 
          Image32by32Left="-224"
          LabelText="Go To Microsoft.com"
          TemplateAlias="o1"
          ToolTipTitle="Navigate to Microsoft.com"
          ToolTipDescription="Just Navigation"/>
      </CommandUIDefinition>
    </CommandUIDefinitions>
    <CommandUIHandlers>
      <CommandUIHandler 
        Command="makeHomePageMS" 
        CommandAction="javascript:navigate('http://www.microsoft.com')">
      </CommandUIHandler>
    </CommandUIHandlers>
  </CommandUIExtension>
</CustomAction>

 

Как видите, для модификации Ленты, элемент CustomAction поддерживает две коллекции: CommandUIHandlers и CommandUIDefinitions. Первая коллекция позволяет определить команды. Тут могут быть части JavaScript, ссылки на подключаемые JavaScript файлы. Кроме того, команды можно назначать динамически. Вторая коллекция, СommandUIDefinitions, содержит определения визуальных изменений внутри Ленты. Так, в нашем случае, элементы CommandUIDefinition заменяют весь код с ID, указанным в Location на наш собственный код. Поскольку первые два элемента CommandUIDefinition не содержат внутреннего кода, то элемент, указанный в Location, просто исчезает из нашей Ленты. В последнем элементе CommandUIDefinition, я просто скопировал существующую кнопку из файла CMDUI.xml, после чего сделал замену заголовка, описания и команды. В результате мы получим Ленту, которая выглядит следующим образом:

@1.5

@1.5 Результат работы приложения

Попробуем переписать элемент CustomAction так, чтобы создать новую закладку на Ленте. При этом ограничим работу закладки на всех страницах, связанных с библиотеками документов (101). Вот код примера:

<CustomAction
  Id="MyActions.Ribbon.CustomButtons"
  Location="CommandUI.Ribbon"
  RegistrationType="List" 
  RegistrationId="101">
  <CommandUIExtension>
    <CommandUIDefinitions>
      <CommandUIDefinition
        Location="Ribbon.Tabs._children">
        <Tab
          Id="Ribbon.CustomTab"
          Title="Custom Tab"
          Description="This is a custom tab"
          Sequence="1001">
          <Scaling
            Id="Ribbon.CustomTab.Scaling">
            <MaxSize
              Id="Ribbon.CustomTab.Scalling.MaxSize"
              GroupId="Ribbon.CustomTab.CustomGroup"
              Size="OneLargeTwoMedium"/>
            <Scale
              Id="Ribbon.CustomTab.Scaling.CustomTabScaling"
              GroupId="Ribbon.CustomTab.CustomGroup"
              Size="OneLargeTwoMedium" />
          </Scaling>
          <Groups Id="Ribbon.CustomTab.Groups">
            <Group
              Id="Ribbon.CustomTab.CustomGroup"
              Description="This is a custom group"
              Title="Custom Group"
              Sequence="52"
              Template="Ribbon.Templates.CustomTemplate">
              <Controls Id="Ribbon.CustomTab.CustomGroup.Controls">
                <Button
                  Id="Ribbon.CustomTab.CustomGroup.Button1"
                  Image32by32="…" 
                  Image32by32Top="-128" 
                  Image32by32Left="-224"
                  Command="CustomTab.Button1Command"
                  Sequence="15"
                  Description="Button1"
                  LabelText="My Button1"
                  TemplateAlias="cust1"/>
                <Button
                  Id="Ribbon.CustomTab.CustomGroup.Button2"
                  Image16by16="…" 
                  Image16by16Top="-200" 
                  Image16by16Left="-32"
                  Command="CustomTab.Button2Command"
                  Sequence="16"
                  Description="Button 2"
                  LabelText="My Button2"
                  TemplateAlias="cust2"/>
                <Button
                  Id="Ribbon.CustomTab.CustomGroup.Button3"
                  Image16by16="…" 
                  Image16by16Top="-200" 
                  Image16by16Left="-32"
                  Command="CustomTab.Button3Command"
                  Sequence="17"
                  Description="Button 3"
                  LabelText="My Button 3"
                  TemplateAlias="cust3"/>
              </Controls>
            </Group>
          </Groups>
        </Tab>
      </CommandUIDefinition>
      <CommandUIDefinition Location="Ribbon.Templates._children">
        <GroupTemplate Id="Ribbon.Templates.CustomTemplate">
          <Layout
            Title="OneLargeTwoMedium"
            LayoutTitle="OneLargeTwoMedium">
            <Section Alignment="Top" Type="OneRow">
              <Row>
                <ControlRef DisplayMode="Large" TemplateAlias="cust1" />
              </Row>
            </Section>
            <Section Alignment="Top" Type="TwoRow">
              <Row>
                <ControlRef DisplayMode="Medium" TemplateAlias="cust2" />
              </Row>
              <Row>
                <ControlRef DisplayMode="Medium" TemplateAlias="cust3" />
              </Row>
            </Section>
          </Layout>
        </GroupTemplate>
      </CommandUIDefinition>
    </CommandUIDefinitions>
    <CommandUIHandlers>
      <CommandUIHandler
        Command="CustomTab.Button1Command"
        CommandAction="javascript:alert('Hello, Button1');" />
      <CommandUIHandler
        Command="CustomTab.Button2Command"
        CommandAction="javascript:alert('Hello, Button2');" />
      <CommandUIHandler
        Command="CustomTab.Button3Command"
        CommandAction="javascript:alert('Hello, Button3');" />
    </CommandUIHandlers>
  </CommandUIExtension>
</CustomAction>

 

Как видно, если мы хотим добавить новые элементы в коллекцию, то используем специальное свойство _children, которое указываем сразу после ID контейнера, разделяя их точкой. Это верно и для коллекции закладок и для коллекции шаблонов типа GroupTemplate.

Код стоит начать рассматривать с определения элемента GroupTemplate, который задает формат отображения создаваемой группы кнопок на нашей закладке. Тут определяется элемент Layout, содержащий элементы Section, отвечающие за отдельные ячейки или столбца в группе элементов. Внутри элементов Section ведется разбиение на строки с помощью элемента Row. Так, в одной секции можно разместить одну большую кнопку или несколько кнопок поменьше. Описание размеров содержится в элементах ControlRef. Тут же содержится имя раздела в шаблоне, куда может быть размещен элемент. Фактически GroupTemplate задает разметку для группы элементов, а элемент определяет, в какой группе он хочет находиться. Ниже приведены четыре возможных размера в разметке:

· Small – только изображение;

· Medium – изображение и текст;

· Large – изображение 32 на 32;

· Text – только текст.

Остальной код описывает три кнопки, содержащиеся в одной группе и использующие описанный шаблон и команды, связанные с этими кнопками. Кроме того, элементы MaxSize и Scale шаблон для свободного размещения групп на нашей закладке, а также шаблон, который будет применен при недостаточном количестве места для отображения групп в развернутом формате. Покольку мы имеем только один шаблон, то разницы между этими элементами нет.

На рисунке ниже показан результат работы кода:

@1.6

@1.6 Результат работы приложения

Written by Sergiy Baydachnyy

24.03.2010 at 16:05

Опубликовано в SharePoint

Tagged with

Запуск Visual Studio 2010, 20 апреля, Киев

6 комментариев

clip_image002
Приглашаем Вас принять участие в конференции «Visual Studio 2010: создание приложений будущего», которая состоится 20 апреля 2010 г.

clip_image004Конференция пройдет в самом центре Киева в здании Кукольного театра по адресу г. Киев, ул. Михаила Грушевского, д. 1 «а».

Участники конференции смогут познакомиться с новыми возможностями Visual Studio 2010 и TFS 2010 для создания современных приложений. Будут рассмотрены вопросы организации гибких процессов разработки, создание насыщенных интернет приложений с использованием Silverlight 4.0, создание решений для Windows Phone 7, а также использование Visual Studio 2010 для разработки решений для Microsoft Office SharePoint 2010 и Microsoft SQL Server 2008 R2. Каждый участник конференции получит стилизованный рюкзак и книгу. После окончания конференции состоится ужин, на котором участники смогут задать вопросы докладчикам и экспертам.

Стоимость участия: 294 грн

Регистрация http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032446868&Culture=UK-UA

Written by Sergiy Baydachnyy

18.03.2010 at 10:13

Опубликовано в Microsoft, Visual Studio 2010

Tagged with

Работа с внешними данными в SharePoint 2010 beta – как чинить

leave a comment »

Столкнулся с проблемай взаимодействия с Business Connectivity Services, о которых пойдет речь в следующем посте. При попытке создать внешний тип данных, используя SharePoint Designer, выдается сообщение об ошибке (ничего полезного в этом сообщении нет). При этом службы запущены, база создана и выглядит все хорошо. На мысль навело сообщение об ошибке, появляющееся при попытке получить доступ к службе через Central Administration: Application Management->Manage Services Applications

image

Тут, при попытке просмотра доступных типов, возникала ошибка, связанная с непониманием атрибута allowInsecureTransport. Чтобы починить проблему, нужно установить специальное обновление:

https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=23806&wa=wsignin1.0

После перезагрузки все работает.

Written by Sergiy Baydachnyy

18.03.2010 at 09:44

Опубликовано в SharePoint

Tagged with

SharePoint 2010: Что нового? (часть 7) – XSLT

with one comment

Еще одно нововведение, которое я хотел бы рассмотреть, это поддержка двух специальных XSLT веб-частей, способных отображать данные из списков, используя XSL преобразования.

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

Итак, в далеком 2002 году, когда на рынок появился SharePoint 2.0, для отображения списков использовалось две веб-части: ListViewWebPart и ListFormWebPart. Первая из двух веб-частей позволяла отобразить данные из списка в виде набора записей (то есть выдать все данные в списке), а вторая веб-часть использовалась для редактирования, создания или отображения отдельной записи. Данные веб-части были крайне «неповоротливые», работали с CAML и практически не давали возможностей модифицировать внешний вид списков. Конечно, с помощью CAML или в дизайнере, разработчик мог задать отображаемые поля, но этим все и ограничивалось.

С выходом SharePoint 2007, набор существующих веб-частей расширили BaseXsltDataWebPart и DataFormWebPart. Если класс BaseXsltDataWebPart описывал основные возможности веб-части, позволяющей отображать данные с использованием XSL преобразования, то его наследник – DataFormWebPart, служил именно для отображения данных из списков, принимая данные от DataSourceControl, выбираемые (обычно) с помощью CAML. Фактически веб-часть DataFormWebPart могла отображать все что угодно, принимая XSL и данные, но чаще использовалась для отображения списка данных. Для отображения отдельного элемента продолжали использовать ListFormWebPart.

Наконец, SharePoint 2010 предлагает две новые веб-части – XsltListFormWebPart и XsltListViewWebPart. Вы не поверите, но обе веб-части являются наследниками DataFormWebPart через промежуточный класс BaseXsltListWebPart. Фактически, основная идея новых веб-частей – адаптировать DataFormWebPart для отображения данных в списках. XsltListFormWebPart и XsltListViewWebPart позволяют скрыть CAML код, сосредоточившись на XSL преобразовании, обеспечив желаемое преставление элемента или всего списка.

Если Вы уже запутались, то ниже я привожу диаграмму соответствующих классов:

clip_image002

Все бы ничего, есть XsltListFormWebPart и XsltListViewWebPart, их и нужно использовать. Если Вы создаете собственные страницы, отображающие данные из списков, то все действительно так, — используйте новые веб-части. Однако, SharePoint 2010 содержит и «старый» код. Создайте сайт на основе шаблона Team Site и откройте созданный сайт в SharePoint Designer 2010. Выберите один из стандартных списков, например Announcement и откройте одну из форм отображения или редактирования отдельного элемента (например, DispForm.aspx):

clip_image004

Тут Вы без труда найдете ListFormWebPart. Это же верно и при создании собственного списка. Между тем, если Вы попробуете добавить новую форму, то тут Вы сможете найти уже DataFormWebPart. При просмотре Views (страниц, отображающих весь список), ситуация совсем иная – тут используется XsltListViewWebPart, как и положено. А вот использование XsltListFormWebPart замечено не было. Более того, я попытался найти хоть что-то об использовании XsltListFormWebPart – ничего. Попробуем разобраться сами.

Итак, работая со списками, XsltListViewWebPart используется достаточно активно, как в существующих списках, так и при создании собственного списка. Несмотря на это, Вы можете добавить экземпляр этой веб-части явно, на любую из страниц. Для этого можно использовать SharePoint Designer. Если же Вы решили использовать интерфейс SharePoint, то у Вас ничего не выйдет. Первая трудность, с которой Вы столкнетесь, — необходимость активировать доступ к XsltListViewWebPart, добавив ее в галерею веб-частей. С этим легко справиться. Но, как только Вы разместите веб-часть на странице, XsltListFormWebPart автоматически настраивается на текущий DataSource, то есть, тут же начинает отображать данные, содержащие список страниц сайта, если Вы ее добавили на обычную страницу, или данные из конкретного списка, если страница относится к списку. Поменять же список с помощью настроек веб-части – нельзя (нет такого свойства в окне свойств). Поэтому, чтобы отобразить произвольный список на произвольной странице, переходим в SharePoint Designer.

SharePoint Designer содержит целую категорию кнопок, позволяющих добавлять отображение списка с помощью XsltListViewWebPart на любую из страниц:

clip_image006

Чтобы отобразить эту категорию, откройте любую страницу и перейдите к редактированию содержимого. Воспользуйтесь вкладкой Insert, чтобы получить доступ к таким кнопкам, как:

· Data View – позволяет отобразить содержимое списка с помощью XsltListFormWebPart. Собственно говоря, эта кнопка нам и нужна;

· Related Item View – позволяет отобразить данные из связанного списка. Поскольку в SharePoint 2010 есть возможность задавать отношения между списками, — это легко сделать;

· New Item Form – создает обычную форму для создания нового элемента. При этом используется веб-часть DataFormWebPart, позволяющая задать XSL преобразование, но пришедшая из предыдущей версии SharePoint;

· Edit Item Form – создает форму для редактирования элемента;

· Display Item Form – создает форму для отображения элемента.

Нажав на Data View, Вы можете выбрать один из доступных списков и отобразить его данные на странице.

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

clip_image008

Так, при редактировании XSL преобразования становятся доступны следующие закладки:

· Design – тут можно выбрать способ представления элементов в виде списка, карточек и т. д. По умолчанию тут 8 стилей, но присутствует ссылка, позволяющая найти еще больше стилей в Интернете;

· Table – тут Вы можете добавлять столбцы в созданную таблицу и редактировать стиль таблицы, отображающей элементы;

· Options – самая интересная закладка, позволяющая задать условные выражения и формулы внутри XSL преобразования. Для этой цели тут есть две кнопки: Conditional Formatting и Formula. Благодаря Conditional Formatting, Вы можете выборочно применять тот или другой стиль к ячейке или целой строке, «разукрашивая» Вашу таблицу, как новогоднюю елку. А с помощью кнопки Formula, Вы можете создавать выражения, базирующиеся на значениях в любом из полей.

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

Итак, с XsltListViewWebPart мы разобрались. Мне удалось найти один недостаток этой веб-части. К сожалению, она не умеет отображать календарь в режиме Calendar View. Как и раньше, для отображения календаря используется специальная веб-часть (даже не веб-часть, а объект класса, загружаемый в стандартную WebPart). Поэтому моя мечта, — разукрасить календарь в разные цвета, в зависимости от типа события, так и не сбылась (опять нужно писать код).

Выше мы говорили, что для работы с набором данных в списке используется XsltListViewWebPart, которую легко добавить с помощью Data View кнопки закладки Insert. Но, если Вы попытаетесь добавить форму создания, редактирования или отображения отдельного элемента любого из списков, используя New Item Form и аналогичные кнопки, то такой веб-части как XsltFormViewWebPart Вы не увидите. Вместо нее используется DataFormWebPart, которая полностью оправдывает себя, но тогда не ясно назначение новой веб-части. Поэтому, если Вы хотите использовать XsltFormViewWebPart, то придется писать код явно. Возможно, что-то поменяется при переходе с бета версии.

Written by Sergiy Baydachnyy

18.03.2010 at 09:34

Опубликовано в SharePoint

Tagged with

Silverlight 4: Обработка ошибок при связывании

leave a comment »

Silverlight 3 поддерживал специальный механизм проверки данных при связывании с элементами управления – ValidatesOnException и NotifyOnValidationError. Первое свойство объекта типа Binding обеспечивало возможность визуального отображения ошибки (например, красный прямоугольник вокруг текстового поля), а второе – обеспечивало механизм перехвата и обработки ошибки в коде. Сама ошибка связывания должна была инициироваться исключением внутри класса, описывающего данные. То есть, если Вы выполняли связывание свойства FirstName класса Employee с текстовым полем, то обработку значения должно было выполнять само свойство и выбрасывать исключения всякий раз, когда устанавливаемое значение выглядело не корректно.

В Silverlight 4 механизм обработки ошибок при связывании был расширен следующими свойствами: ValidatesOnDataErrors и ValidatesOnNotifyDataErrors

ValidatesOnDataErrors

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

Рассмотрим простой класс Employee, реализующий интерфейс IDataErrorInfo. Приведем весь код этого класса:

   1:  public class Employee: 
   2:     INotifyPropertyChanged, IDataErrorInfo
   3:  {
   4:      public event PropertyChangedEventHandler PropertyChanged;
   5:   
   6:      public void OnPropertyChanged(PropertyChangedEventArgs e)
   7:      {
   8:          if (PropertyChanged != null)
   9:              PropertyChanged(this, e);
  10:      }
  11:   
  12:      private string firstName;
  13:      private string lastName;
  14:      private int age;
  15:      private string email;
  16:      private double salary;
  17:   
  18:      public double Salary
  19:      {
  20:          get 
  21:          { 
  22:              return salary; 
  23:          }
  24:          set 
  25:          { 
  26:              salary = value;
  27:              OnPropertyChanged(new PropertyChangedEventArgs("Salary"));
  28:          }
  29:      }
  30:   
  31:      public string FirstName
  32:      {
  33:          get { return firstName; }
  34:          set 
  35:          { 
  36:              firstName = value; 
  37:              OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
  38:          }
  39:      }
  40:   
  41:      public string LastName
  42:      {
  43:          get { return lastName; }
  44:          set
  45:          {
  46:              lastName = value;
  47:              OnPropertyChanged(new PropertyChangedEventArgs("LastName"));
  48:          }
  49:      }
  50:   
  51:      public string EMail
  52:      {
  53:          get { return email; }
  54:          set
  55:          {
  56:              email = value;
  57:              OnPropertyChanged(new PropertyChangedEventArgs("EMail"));
  58:          }
  59:      }
  60:   
  61:      public int Age
  62:      {
  63:          get { return age; }
  64:          set
  65:          {
  66:              age = value;
  67:              OnPropertyChanged(new PropertyChangedEventArgs("Age"));
  68:          }
  69:      }
  70:   
  71:      public override string ToString()
  72:      {
  73:          return String.Format("{0} {1}", firstName, lastName);
  74:      }
  75:   
  76:      string errors = null;
  77:   
  78:      public string Error
  79:      {
  80:          get { return errors; }
  81:      }
  82:   
  83:      public string this[string columnName]
  84:      {
  85:          get
  86:          {
  87:              string result = null;
  88:              if (columnName == "Age")
  89:              {
  90:                  if (Age <= 0)
  91:                  {
  92:                      result = "Age should be positive!";
  93:                  }
  94:                  else if (Age <= 16)
  95:                  {
  96:                      result = "You are too young!";
  97:                  }
  98:              }
  99:              return result;
 100:          }
 101:      }
 102:  }

Как видите, проверка свойств выносится в реализацию индексатора, описываемого интерфейсом IDataErrorInfo. При этом, реализация проверки базируется на проверке свойства, которое уже установлено (пусть даже в неправильное значение).

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

Чтобы инициировать выдачу сообщений об ошибках, описанных в индексаторе, нужно воспользоваться свойством класса BindingValidatesOnDataErrors:

<TextBlock Text="Age:" Grid.Row="3" Grid.Column="0"></TextBlock>
<TextBox Text=
   "{Binding Path=Age, Mode=TwoWay, ValidatesOnDataErrors=True,
     NotifyOnValidationError=True}"
   BindingValidationError="TextBox_BindingValidationError"
   Grid.Row="3" Grid.Column="1">
</TextBox>

Естественно, что ValidatesOnDataErrors и ValidatesOnExceptions не могут отрабатывать одновременно. Иными словами, если у Вас есть готовый класс, описывающий некоторый объект, при этом его свойства выполняют проверку данных и выбрасывают исключения, то ValidatesOnDataErrors использовать нельзя, так как он полностью игнорируется при появлении исключения (даже если ValidatesOnExceptions установлен в false).

 

ValidatesOnNotifyDataErrors

К сожалению, не всегда данные можно проверить сразу же на клиенте. Очень часто необходимо обратиться к источнику данных, который расположен на удаленном сервере. Лишь после этого можно сделать вывод о корректности данных. Естественно, что описанные выше механизмы не подходят для удаленной проверки данных, так как заблокируют интерфейс на время соединения с источником данных. Поэтому Silverlight 4 представляет новый механизм, позволяющий вести асинхронную проверку данных.

Чтобы обеспечить асинхронную проверку данных, класс, описывающий данные, должен реализовывать интерфейс INotifyDataErrorInfo. Тут описаны свойство HasErrors, определяющее наличие ошибок при асинхронной проверке данных, метод GetErrors, возвращающий объект перечислимого типа, содержащий ошибки, а также событие ErrorsChanged, которое инициируется при любом изменении коллекции ошибок.

Чтобы активировать работу интерфейса INotifyDataErrorInfo, необходимо воспользоваться свойством класса Binding – ValidatesOnNotifyDataErrors, установив его значение в true.

Особенностью этого подхода является возможность его комбинации с описанными выше подходами.

Written by Sergiy Baydachnyy

15.03.2010 at 09:33

Опубликовано в SilverLight

Tagged with

Перерыв

8 комментариев

Долго ничего не писал. Все от того, что к запуску Visual Studio 2010, который состоится 20 апреля в Киеве, мы хотели каждому участнику события выдать книгу по Silverlight 4.

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

По Silverlight 5 будет лучше, так как можно будет использовать уже готовый материал, да и время поджимать не будет.

Ниже привожу содержание книги:

Глава 1. Введение в Silverlight 4

Глава 2. Начинаем работу с Silverlight

Глава 3. Архитектура Silverlight

Глава 4. Использование XAML

Глава 5. Элементы управления и события

Глава 6. Привязка к данным

Глава 7. Взаимодействие с сервером

Глава 8. Графика, трансформация и анимация

Глава 9. Работа с аудио и видео

Глава 10. Ресурсы и стили

Глава 11. Создание шаблонов элементов управления

Глава 12. Отладка приложений и тестирование

Глава 13. Создание сложных приложений

Глава 14. Использование Deep Zoom

Глава 15. Интеграция с SharePoint 2010

Глава 16. Введение в Microsoft Expression Studio

Written by Sergiy Baydachnyy

04.03.2010 at 16:33

Опубликовано в SilverLight

Tagged with