如何在 Visual Studio TFS API (VS2015) 中将工作项关联为 "Associate" 或 "Resolve"?

How to Associate an work item as "Associate" or "Resolve" in Visual Studio TFS API (VS2015)?

我用下面的代码创建了一个项目:

var pc = ParentSection.GetService<IPendingChangesExt>();

var model = pc.GetType().GetField("m_workItemsSection", BindingFlags.NonPublic | BindingFlags.Instance);
var t = model.FieldType;
var mm = model.GetValue(pc);

var m = t.GetMethod("AddWorkItemById", BindingFlags.NonPublic | BindingFlags.Instance);

m.Invoke(mm, new object[] { selectedWorkItemId });

这会将一个工作项按其 ID 添加到当前待定的更改中。

现在,我想 link 在 "Associate" 或 "Resolve" 之间选择工作项(关联和解析),具体取决于用户在插件界面上单击的按钮,如下所示:

如果用户单击 'Associate and resolve',工作项应关联并在签入时标记为已解决。

如果用户单击 'Associate only',工作项必须只 link 编辑到变更集,而不是解析。

欢迎任何帮助

这不是 WorkItem 的 属性。这是工作项上的签入操作。详情可以参考这个linkChanging the Default CheckIn Option to Associate in TFS 2012

您可能需要使用 CheckinWorkItemAction 枚举。来自 MSDN.

的更多详细信息

关于 TFS - VS Extension: Add work item to pending changes via API and also check this link: C# Programmatically Checking in code changes with TFS API while associating the changeset to a Work Item

的类似问题

更新

如果您想将默认状态'resolve'更改为'associate',您需要

  • 更改设置注册表项 HKEY_CURRENT_USER\Software\Microsoft\VisualStudiox.0\TeamFoundation\SourceControl\Behavior\ResolveAsDefaultCheckinAction to False.

  • 或者对于 VS2015,有一个选项 Tools > Options > Source Control > Visual Studio Team Foundation >“解决关联的工作项 签到。

注意:以上两项仅影响您的客户端计算机。

否则,对于所有用户,您需要为您正在使用的工作项类型(错误、任务等)编辑工作项模板定义。详细步骤可以参考这个问题How to disable auto done status for task in checkin

工作项和变更集之间只有一种link类型,link信息存储在工作项中。 Visual Studio中"Associate"和"Resolve"的区别是"Associate"只link工作项要变更集而"Resolve"会改变工作项的状态在 link 将工作项更改为变更集后将工作项更改为 "Resolved"。

如果您正在开发自己的插件,则需要手动编写代码来实现这些功能。

以下代码显示如何将工作项link添加到变更集:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace APPI
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://xxx.xxx.xxx.xxx:8080/tfs/DefaultCollection";
            TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(url));
            WorkItemStore wis = ttpc.GetService<WorkItemStore>();
            VersionControlServer vcs = ttpc.GetService<VersionControlServer>();
            int wid = 82;
            int cid = 332;
            WorkItem wi = wis.GetWorkItem(wid);
            Changeset cs = vcs.GetChangeset(cid);
            ExternalLink el = new ExternalLink(wis.RegisteredLinkTypes["Fixed in Changeset"], cs.ArtifactUri.AbsoluteUri);
            wi.Links.Add(el);
            wi.Save();     
        }
    }
}

看,我已经完成了,但我知道这是错误的:

使用问题代码包含工作项后:

IPendingChangesExt pendingChangesExt = ParentSection.GetService<IPendingChangesExt>();

var workItemSection = pendingChangesExt.GetType().GetField("m_workItemsSection", BindingFlags.NonPublic | BindingFlags.Instance);

var modelType = workItemSection.FieldType;
var model = workItemSection.GetValue(pendingChangesExt);

var m = modelType.GetMethod("AddWorkItemById", BindingFlags.NonPublic | BindingFlags.Instance);                

m.Invoke(model, new object[] { selectedWorkItemId });

我添加了一些新代码(这些是不同的功能,好吗?)...这第二次调用将等待工作项出现在待定更改 'Related Work Items' 部分,并将更改其关联从决心到联想 'manually'.

IPendingChangesExt pendingChangesExt = ParentSection.GetService<IPendingChangesExt>();

var model = pendingChangesExt
                     .GetType()
                     .GetField("m_workItemsSection", BindingFlags.NonPublic | BindingFlags.Instance);

var modelType = model.FieldType;
var workItemSection = model.GetValue(pendingChangesExt);

var selectedWil = workItemSection
                              .GetType()
                              .GetProperty("SelectedWorkItems")
                              .GetValue(workItemSection) as ObservableCollection<WorkItemValueProvider>;

var availablWil = workItemSection
                              .GetType()
                              .GetProperty("WorkItemsListProvider")
                              .GetValue(workItemSection) as WorkItemsListProvider;

// Waiting for section to be ready to start association
while (!availablWil.WorkItems.Where(x => x.Id == selectedWorkItemId).Any())
{                    
    await System.Threading.Tasks.Task.Delay(25);
}

selectedWil.Clear();
selectedWil.Add(availablWil.WorkItems.Where(x => x.Id == selectedWorkItemId).First());

EnvDTE80.DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;
dte2.ExecuteCommand("TeamFoundationContextMenus.WorkItemActionLink.TfsContextPendingChangesPageWorkItemActionLinkAssociate");

selectedWil.Clear();

尽管这段代码很有效,但我仍在为 运行 第二种方法寻求更好的解决方案。在评论中建议的 'default value' 将不起作用,因为开发人员应该只能 associate/resolve 选择按钮。