Использование пользовательских расширений для рабочих элементов TFS - Решение для динамических списков
ОГЛАВЛЕНИЕ
Решение для динамических списков
Ниже предлагается два из возможных решений реализации динамических списков на форме рабочего элемента:
- Использование одного расширения для нескольких полей – в этом случае предполагается использование одного пользовательского элемента, который включает в себя несколько выпадающих списков, для нескольких полей рабочего элемента;
- Использование событий рабочего элемента – используется одно расширение как выпадающий список для каждого поля и для выполнения изменения состава списков используется событие изменения значения поля рабочего элемента.
Использование одного элемента для нескольких полей
Как говорилось выше, суть данного подхода заключается в использовании одного пользовательского расширения, который включает несколько выпадающих списков, для нескольких полей. В нашем случае мы реализуем два выпадающих списка (см. Рисунок 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)

Использование событий рабочего элемента
Второй метод – это использование событий рабочего элемента, в частности обработка события изменения значения для его полей. Для этого в пользовательском расширении необходимо установить обработчик события FieldChanged, когда устанавливается свойство WorkItemDatasource .
private WorkItem m_workItem; m_workItem = (WorkItem)value; |
Примечание: Важно чтоб обработчик событий был удален, перед тем как сменится объект рабочего элемента в пользовательском расширении (свойство 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. Определение пользовательского элемента на форме