Использование пользовательских расширений для рабочих элементов TFSИсточник: cmcons Шамрай Александр
Очень часто возникает ситуация, когда стандартный набор функций используемой системы перестает удовлетворять ее пользователей или возникает необходимость "скрестить" текущую систему с другой. Данная статья описывает дополнительные возможности Team Foundation Server, которые можно использовать при создании и модификации шаблонов процессов для расширения стандартных возможностей системы. ВведениеСтандартный набор элементов пользовательского интерфейса и его возможности не всегда удовлетворяют взыскательных пользователей любой системы. И MS Visual Studio Team Foundation Server (TFS), в этом смысле, не является исключением. Однако в TFS предусмотрена возможность создания пользовательских элементов для расширения стандартных свойств рабочих элементов системы. Использование технологий ".NET" позволяет просто создавать пользовательские расширения и интегрировать их в свою форму управления рабочим элементом. В данной статье описывается возможность создания дополнительных пользовательских элементов графического интерфейса на простом примере реализации связанных списков и сравнение со стандартной возможностью организации связанных списков. Стандартные спискиДля формирования связанных списков нам помогут встроенные глобальные списки (элемент GLOBALLIST). Глобальные списки очень удобны при работе с часто меняющимися списками и большими списками и одни и те же списки могут использоваться в различных рабочих элементах. Для нашего примера мы создадим несколько глобальных списков (см. Рисунок 1):
Рисунок 1. Глобальные списки Далее необходимо создать два текстовых поля, которые буду хранить в себе информацию о выбранных полях:
Рисунок 2. Новые поля Теперь необходимо для каждого поля определить список. Особенность в нашем случае заключается в том, что для поля "OS Type" должен быть статический список, а для поля "OS Version" необходимо определить динамический список, которые будет менять свой набор значений в зависимости от значения, которое выбрано в поле "OS Type". Для того чтоб подключить список к полю "OS Type", для него необходимо указать правило "ALLOWEDVALUES" и в нем установить ссылку на глобальный список "Operating systems" как изображено на рисунке ниже (см. Рисунок 3). Рисунок 3. Подключение списка к полю Для поля "OS Version" необходимо определить условия, по которым будет изменяться содержимое его списка. Для этого необходимо для поля определить правило "WHEN", которое выполнится при истинности прописанного в нем выражения. Правило "WHEN" может отслеживать изменения значения любого поля, которое принадлежит рабочему элементу. Как условие определим соответствие значения ссылки "CMC.Bug.OSType", которая определяет поле "OS Type", каждому значению из глобального списка "Operating systems" (см. Рисунок 4). Рисунок 4. Определение условия для поля Результатом выполнения правила должно быть установка в значение "ALLOWEDVALUES" наименования необходимого глобального списка (одного из "OS Microsoft Windows", "OS Linux" и т.д.) Рисунок 5. Подключение списка к условию
И на последнем шаге необходимо новые поля разместить на форме рабочего элемента, которые должны иметь встроенный тип стандартного элемента пользовательского интерфейса "FieldControl" (см. Рисунок 6).
Рисунок 6. Определение полей на форме Результатом проведенных изменений на форме должны быть два списковых поля с зависимыми значениями (см. Рисунок 7). Рисунок 7. Новые поля на форме рабочего элемента В примере используется статичный набор данных для каждого списка. Если же планируется использование динамических данных для глобальных списков, допустим, с внешних источников, можно написать внешнее приложение, которое будет получать информацию и обновлять ее с помощью утилиты импорта глобального списка из командной строки glimport. Использование пользовательских элементовНе всегда использование встроенных элементов пользовательского интерфейса удовлетворяют необходимым условиям их использования. Для расширения возможностей и более гибкой работы с данными рекомендуется применять пользовательские расширения для интерфейса. Вот некоторые причины, которые могут подтолкнуть к использованию пользовательских элементов для динамических списков:
Подготовка проектаДля создания и редактирования пользовательских расширений интерфейса используется среда разработки MS Visual Studio 2005 или 2008, причем, использование одного и того же расширения допускается в обоих версиях MS Visual Studio. Для нового пользовательского элемента необходимо создавать проект как "Windows Control Library" (см. Рисунок 8). Открыть в полный размер' href="http://cmcons.com/images/tfs_custom_control/8.png" target=_blank style=color:white;>Открыть в полный размер' href="http://cmcons.com/images/tfs_custom_control/8.png" target=_blank>
Рисунок 8. Создание нового проекта Кроме того, класс, который создается, должен реализовывать интерфейс "IWorkItemControl". Этот интерфейс определен в сборке "Microsoft.TeamFoundation.WorkItemTracking.Controls.dll", которая обычно находится в каталоге "<Диск>:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies". Также необходим доступ к сборке "Microsoft.TeamFoundation.WorkItemTracking.Client.dll", в которой находится описание основных классов, которые необходимы для работы с рабочим элементом. Для того, чтоб получить доступ к интерфейсу и к основным классам рабочего элемента, необходимо добавить ссылку на сборки "Microsoft.TeamFoundation.WorkItemTracking.Controls.dll" и "Microsoft.TeamFoundation.WorkItemTracking.Client.dll" (см. Рисунок 9) и добавить в исходный код строки:
Рисунок 9. Ссылки на сборки Интерфейс "IWorkItemControl" имеет следующие важные составляющие (см. Таблица 1): Таблица 1. Элементы интерфейса "IWorkItemControl"
В результате для нового пользовательского элемента должен получиться листинг, который приведен ниже.
Регистрация пользовательского элементаПеред началом использования пользовательского расширения и его отладкой, dll-файл, который содержит расширение, необходимо разместить в определенном месте. Все пользовательские элементы для MS Visual Studio 2005 находятся в специальной папке "Microsoft\Team Foundation\Work Item Tracking\Custom Controls", местонахождение которой система определяет в следующей последовательности:
Если Вы используете MS Visual Studio 2008, то пользовательские элементы размещаются в подкаталоге "9.0" вышеприведенного каталога. Такой подход сделан для тех случаев, если на одном рабочем месте используются MS Visual Studio 2005 и MS Visual Studio 2008. Примечание: Если на одном рабочем месте используются MS Visual Studio 2005 и MS Visual Studio 2008, то важно помнить, что пользовательское расширение необходимо перекомпилировать под каждую среду, в которой оно будет использоваться. Это связано с различными dll-зависимостями для каждой среды. Кроме этого необходимо определить для каждого пользовательского расширения специальный (.wicc) файл, в котором находится описание элемента. Этот файл должен находиться вместе с dll-файлом пользовательского элемента и иметь наименование как "<имя_элемента>.wicc". Файл описания расширения представляет собой xml-файл и имеет следующую структуру: <?xml version="1.0"?> Как видно из структуры, файл описания определяет следующее:
Отладка проектаДля отладки пользовательского расширения можно использовать другую запущенную копию MS Visual Studio, в которой это расширение будет использоваться. Для этого необходимо сконфигурировать опцию отладки проекта, как это изображено на рисунке ниже (см. Рисунок 10) для MS Visual Studio 2005. Рисунок 10. Конфигурирование отладки для MS Visual Studio 2005
Размещение элемента на формеДля редактирования форм, состава полей и состояний рабочего элемента используются два подхода:
Решение для динамических списков
Ниже предлагается два из возможных решений реализации динамических списков на форме рабочего элемента:
Использование одного элемента для нескольких полей
Как говорилось выше, суть данного подхода заключается в использовании одного пользовательского расширения, который включает несколько выпадающих списков, для нескольких полей. В нашем случае мы реализуем два выпадающих списка (см. Рисунок 11) для двух полей "OS Type" и "OS Version", которые были созданы ранее. Рисунок 11. Определение на форме общего элемента Указывать наименование поля при размещении такого пользовательского расширения нет смысла, т.к. он будет устанавливать значение сразу для нескольких полей. Также не указывается метка элемента, т.к. все объекты уже подписаны. Основная идея этого пользовательского расширения заключается в том, что установка нового значения в поля рабочего элемента происходит на событиях изменения выбранного индекса выпадающего списка.
Результат работы формы с пользовательским расширением изображен на рисунке ниже (см. Рисунок 12) Рисунок 12. Пользовательский элемент на форме
Использование событий рабочего элементаВторой метод - это использование событий рабочего элемента, в частности обработка события изменения значения для его полей. Для этого в пользовательском расширении необходимо установить обработчик события FieldChanged, когда устанавливается свойство WorkItemDatasource .
Примечание: Важно чтоб обработчик событий был удален, перед тем как сменится объект рабочего элемента в пользовательском расширении (свойство WorkItemDatasource), т.к. пользовательский элемент будет продолжать получать события от объекта, даже если форма уже была закрыта. Также, пользовательское расширение не будет выгружено из памяти, пока объект рабочего элемента не будет выгружен, что может привести к утечке памяти. Этот обработчик будет вызываться при изменениях значений любых полей рабочего элемента, поэтому при обработке события нужно отслеживать поле-источник, в нашем случае поле "OS Type".
Для каждого пользовательского элемента на форме устанавливается наименование поля и наименование метки поля (см. Рисунок 13). Рисунок 13. Определение пользовательского элемента на форме ЗаключениеИспользование пользовательских элементов для форм рабочих элементов в TFS позволяет расширить стандартные возможности системы и модифицировать их под нужды своей организации. Использование возможностей создания пользовательских расширений далеко не ограничено созданием объектов графического интерфейса, т.к. они позволяют внедрять не только элементы графического интерфейса, но и выполнять внешние приложения, что можно использовать для интеграции с различными внешними системами. Кроме этого, пользовательские расширения позволяют модифицировать логику поведения не только отдельных полей на форме, но и формы рабочего элемента в целом, т.к. ничего не мешает создать свою отдельную форму для рабочего элемента и "перенести" часть логики поведения этого элемента на новую форму. |