如何在 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 选择按钮。
我用下面的代码创建了一个项目:
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 选择按钮。