Використання розширення користувачем робочих елементів TFS

Дуже часто виникає ситуація, коли стандартний набір функцій використовуваної системи перестає задовольняти її користувачів або виникає необхідність "схрестити" поточну систему з іншого. Дана стаття описує додаткові можливості 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).


 

Малюнок 8. Створення нового проекту


Крім того, клас, який створюється, повинен реалізовувати інтерфейс "IWorkItemControl ". Цей інтерфейс визначений у збірці"Microsoft.TeamFoundation.WorkItemTracking.Controls.dll", Яка зазвичай знаходиться в каталозі"<Диск>: Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssemblies". Також необхідний доступ до збірки"Microsoft.TeamFoundation.WorkItemTracking.Client.dll", В якій знаходиться опис основних класів, які необхідні для роботи з робочим елементом. Для того, щоб отримати доступ до інтерфейсу і до основних класів робочого елементу, необхідно додати посилання на складання "Microsoft.TeamFoundation.WorkItemTracking.Controls.dll"І"Microsoft.TeamFoundation.WorkItemTracking.Client.dll"(Див. Малюнок 9) і додати в вихідний код рядки:





using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Controls;

Малюнок 9. Посилання на складання


Інтерфейс "IWorkItemControl"Має наступні важливі складові (див. Таблиця 1):


Таблиця 1.Елементи інтерфейсу "IWorkItemControl















































Найменування
 
Тип
 
Опис
 
 WorkItemDatasource  Властивість Визначає доступ до об'єкта робочого елементу. Для використання цієї властивості, його необхідно приводити до типу WorkItem (Визначення цього типу описано в складанні "Microsoft.TeamFoundation.WorkItemTracking.Controls.dll“)
 WorkItemFieldName  Властивість Властивість визначає найменування поля, з яким асоційований користувальницький елемент. Користувацький елемент може бути асоційований з одним полем або не асоційований зовсім.
 InvalidateDatasource  Метод Цей метод використовується для перемальовування користувацького елемента.
 SetSite  Метод Передає покажчик на інтерфейс IServiceProvider. Використовується якщо необхідно отримати доступ сервісів VS Services.
 Clear  Метод Використовується для скидання вмісту користувацького елемента.
 Properties  Властивість Дає доступ до всіх атрибутів, які були встановлені для цього користувача елемента при описі робочого елементу.
 BeforeUpdateDatasource  Оброблювач події Події викликаються перед і після оновлення значень об'єкту WorkItem відповідно. Коли значення, яке встановлено в призначеному для користувача елементі, змінюється, форма робочого елемента виконує для всіх елементів (через виклик методу InvalidateDatasource) Для оновлення їх значень.
 AfterUpdateDatasource  Оброблювач події
 ReadOnly  Властивість Визначає доступ тільки для читання до призначеного для користувача елементу.
 FlushToDatasource  Метод Користувацький елемент запитується для скидання значення в об'єкт робочого елементу. Зазвичай викликається при операції збереження або коли вийшли з форми робочого елементу. Цей метод можна не використовувати, якщо значення користувацького елемента встановлюється в об'єкт робочого елементу відразу після його зміни.

У результаті для нового користувальницького елемента повинен вийти лістинг, який наведено нижче.







using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Controls;

namespace DependentComboBox
{
public partial class DependentComboBoxControl: UserControl, IWorkItemControl
    {
        public DependentComboBoxControl()
        {
            InitializeComponent();            
        }


        #region IWorkItemControl Members
    }
}


Реєстрація користувача елемента


Перед початком використання користувацького розширення і його налагодженням, dll-файл, який містить розширення, необхідно розмістити в певному місці. Всі користувальницькі елементи для MS Visual Studio 2005 знаходяться у спеціальній папці "MicrosoftTeam FoundationWork Item TrackingCustom Controls", Місцезнаходження якої система визначає в такій послідовності:



  1. У першу чергу пошук папки проводиться по дорозі "Environment.SpecialFolder.CommonApplicationData“;

  2. Далі по дорозі "Environment.SpecialFolder.LocalApplicationData“.

Якщо Ви використовуєте 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″?>
<CustomControl Xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Assembly>DependentComboBox.dll</Assembly>
<FullClassName> DependentComboBox.DependentComboBoxControl </ FullClassName>
</CustomControl>

Як видно зі структури, файл опису визначає наступне:



Налагодження проекту


Для налагодження користувацького розширення можна використовувати іншу запущену копію MS Visual Studio, В якій це розширення буде використовуватися. Для цього необхідно налаштувати опцію налагодження проекту, як це зображено на малюнку нижче (див. Малюнок 10) для MS Visual Studio 2005.

Малюнок 10. Конфігурування налагодження для MS Visual Studio 2005

Розміщення елемента на формі


Для редагування форм, складу полів і станів робочого елемент використовуються два підходи:



  1. За допомогою спеціального xml-файлу, який використовується для опису робочих елементів, і утиліт імпорту (witimport) і експорту (witexport) робочих елементів з шаблону процесу на сервері. З правилами редагування і складом xml-файл, можна ознайомитися за адресою http://msdn.microsoft.com/en-us/library/ms243849.aspx;

  2. За допомогою графічного редактора шаблону процесу, який входить до складу утиліт Team Foundation Server Power Tools. Завантажити і переглянути повну інформацію про цей продукт можна:


    • Для MS Visual Studio 2005 – http://msdn2.microsoft.com/en-us/teamsystem/aa718351.aspx ;

    • Для MS Visual Studio 2008 – http://msdn.microsoft.com/tfs2008/bb980963.aspx .

Рішення для динамічних списків


Нижче пропонується два з можливих рішень реалізації динамічних списків на формі робочого елементу:



  1. Використання одного розширення для декількох полів – у цьому випадку передбачається використання одного користувальницького елемента, який включає в себе кілька випадаючих списків, для кількох полів робочого елементу;

  2. Використання подій робочого елементу – використовується одне розширення як випадаючий список для кожного поля і для виконання зміни складу списків використовується подія зміни значення поля робочого елемента.

Використання одного елемента для декількох полів


Як говорилося вище, суть даного підходу полягає у використанні одного користувача розширення, який включає декілька випадаючих списків, для кількох полів. У нашому випадку ми реалізуємо два випадаючих списку (див. Малюнок 11) для двох полів "OS Type" і "OS Version", які були створені раніше.

 

Малюнок 11. Визначення на формі загального елемента


Вказувати найменування поля при розміщенні такого користувача розширення немає сенсу, тому що він буде встановлювати значення відразу для декількох полів. Також не вказується мітка елемента, тому що всі об'єкти вже підписані. Основна ідея цього користувача розширення полягає в тому, що встановлення нового значення в поля робочого елемента відбувається на подіях зміни обраного індексу випадаючого списку.





string [] OSTypes = {"Microsoft Windows", "Linux", "Novell Netware", "Sun Solaris"};
string[] OSMSVer = { “95”, “98”, “2000”, “Me”, “XP”};
string [] OSLVer = {"Red Hat", "SuSE", "Madrake", "Mandriva", "Ubuntu"};
string[] OSNovVer = { “NetWare 5”, “NetWare 6” };
string[] OSSunVer = { “Solaris 9”, “Solaris 10” };

/ / Збереження поля "OS Type" і створення списку для версій

private void OpSystem_SelectedIndexChanged (object sender, EventArgs e)
{
    if (m_workItem == null) return;
        string OSType = OpSystem.Text;

if (m_workItem.Fields ["OS Type"]. Value.ToString () == OpSystem.Text)
OpVersion.SelectedIndexChanged -= OpVersion_SelectedIndexChanged;

    switch (OSType)
    {
case "Microsoft Windows": OpVersion.DataSource = OSMSVer; break;
         case “Linux”: OpVersion.DataSource = OSLVer; break;
case "Novell Netware": OpVersion.DataSource = OSNovVer; break;
case "Sun Solaris": OpVersion.DataSource = OSSunVer; break;
    }

if (m_workItem.Fields ["OS Type"]. Value.ToString () == OpSystem.Text)
    {
OpVersion.Text = m_workItem.Fields ["OS Version"]. Value.ToString ();
OpVersion.SelectedIndexChanged + = OpVersion_SelectedIndexChanged;
    }

if (m_workItem.Fields ["OS Type"]. Value.ToString ()! = OpSystem.Text)
    {
        m_workItem.Fields[“OS Type”].Value = OpSystem.Text;

        OpVersion.Text = “”;
    }
}

/ / Збереження поля "OS Version" і створення списку для версій

private void OpVersion_SelectedIndexChanged (object sender, EventArgs e)
{
    if (m_workItem == null) return;

if (m_workItem.Fields ["OS Version"]. Value.ToString ()! = OpVersion.Text)
        m_workItem.Fields[“OS Version”].Value = OpVersion.Text;
}
 

Результат роботи форми з призначеним для користувача розширенням зображений на малюнку нижче (див. Малюнок 12)

Малюнок 12. Користувацький елемент на формі

Використання подій робочого елементу


Другий метод – це використання подій робочого елементу, зокрема обробка події зміни значення для його полів. Для цього в користувальницькому розширенні необхідно встановити обробник події FieldChanged, Коли встановлюється властивість WorkItemDatasource






 

private WorkItem m_workItem;
object IWorkItemControl.WorkItemDatasource
{
    get
    {
        return m_workItem;
    }
    set
    {
/ / Видалення події при обнулення об'єкта
        if (value == null && m_workItem != null)
            m_workItem.FieldChanged -= m_workItem_FieldChanged;


        m_workItem = (WorkItem)value;

        if (m_workItem != null)
        {
m_workItem.FieldChanged + = new WorkItemFieldChangeEventHandler (m_workItem_FieldChanged);
/ / Установка схраненних значень для полів
           if (m_fieldName == “CMC.Bug.OSType”)
comboBoxCtrl.Text = m_workItem.Fields ["OS Type"]. Value.ToString ();
            if (m_fieldName == “CMC.Bug.OSVersion”)
            {
SetVersionSource (m_workItem.Fields ["OS Type"]. Value.ToString ());
comboBoxCtrl.Text = m_workItem.Fields ["OS Version"]. Value.ToString ();
            }
        }
    }
}


Примітка: Важливо щоб обробник подій був видалений, перед тим як зміниться об'єкт робочого елементу в призначеному для користувача розширенні (властивість WorkItemDatasource), Тому що користувальницький елемент буде продовжувати отримувати події від об'єкта, навіть якщо форма вже була закрита. Також, для користувача розширення не буде вивантажено з пам'яті, поки об'єкт робочого елементу не буде вивантажений, що може призвести до витоку пам'яті.


Цей оброблювач буде викликатися при змінах значень будь-яких полів робочого елементу, тому при обробці події потрібно відстежувати полі-джерело, в нашому випадку поле "OS Type".






void m_workItem_FieldChanged (object sender, WorkItemEventArgs e)
{
if (! this.IsDisposed & & e.Field! = null & & e.Field.Name == "OS Type"
        && this.m_fieldName == “CMC.Bug.OSVersion”)
    {
        SetVersionSource(e.Field.Value.ToString());
    }
}

/ / Встановлення нових значень для списку версій

private void SetVersionSource(string ostype)
{
    switch (ostype)
    {
case "Microsoft Windows": comboBoxCtrl.DataSource = OSMSVer; break;
        case “Linux”: comboBoxCtrl.DataSource = OSLVer; break;
case "Novell Netware": comboBoxCtrl.DataSource = OSNovVer; break;
case "Sun Solaris": comboBoxCtrl.DataSource = OSSunVer; break;
        default: comboBoxCtrl.DataSource = OSMSVer;
/ * Для нового воркітема за замовчуванням "Microsoft Windows" * /
        break;
    }
}
 


Для кожного користувача елемента на формі встановлюється найменування поля і найменування мітки поля (див. Малюнок 13).

Малюнок 13. Визначення користувацького елемента на формі


Висновок


Використання призначених для користувача елементів для форм робочих елементів у TFS дозволяє розширити стандартні можливості системи і модифікувати їх під потреби своєї організації. Використання можливостей створення користувальницьких розширень далеко не обмежена створенням об'єктів графічного інтерфейсу, тому що вони дозволяють впроваджувати не тільки елементи графічного інтерфейсу, але й виконувати зовнішні програми, що можна використовувати для інтеграції з різними зовнішніми системами. Крім цього, призначені для користувача розширення дозволяють модифіковані логіку поведінки не тільки окремих полів на формі, а й форми робочого елементу в цілому, тому що нічого не заважає створити свою окрему форму для робочого елементу і "перенести" частина логіки поведінки цього елемента на нову форму.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*