是的你可以。TFS 工作项是可定制的。在这个版本中没有我想要的那么多,但你可以做你想做的事。
让我们使用以下字段定义来尝试一下。Notes Date 和 Notes Author 是只读的,并从系统中获取它们的默认值。Notes 字段是 HTML,您可以在其中放置任何您想要的内容。您可以在TFS Process Editor中执行此操作。
<FIELD reportable="dimension" type="DateTime" name="Notes Date" refname="System.VSTS.Notes.Date">
<DEFAULT from="clock" />
<READONLY not="[Global]\Team Foundation Administrators" />
</FIELD>
<FIELD reportable="dimension" type="String" name="Notes Author" refname="System.VSTS.Notes.Author">
<DEFAULT from="currentuser" />
<READONLY not="[Global]\Team Foundation Administrators" />
</FIELD>
<FIELD type="HTML" name="Notes" refname="System.VSTS.Notes" />
</FIELDS>
当然,您仍然需要在表单中添加控件。
您可以尝试的另一件事是仅保留 Notes 字段并注册 WorkItemChanged 事件并编写 Web 服务以使用 Date 和 Author 更新 notes 字段。Changed BY 和 Changed Date 字段将为您提供此信息。您可以在 Brian A. Randell - Team Foundation System Event Service的这篇文章中了解可用事件以及如何订阅它们
[WebService(Namespace = "http://mynamespace.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class UpdateWorkItem : System.Web.Services.WebService
{
private static TeamFoundationServer _Tfs;
private static WorkItemStore _WorkItemStore;
private static List<WorkItem> _ChangedWorkItems = new List<WorkItem>();
[SoapDocumentMethod(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
[WebMethod]
public void Notify(string eventXml, string tfsIdentityXml)
{
EventLog.WriteEntry("TFS Services", "Log Started: Notify Webmethod");
// Load the recieved XML into a XMLDocument
XmlDocument eventXmlDoc = new XmlDocument();
eventXmlDoc.LoadXml(eventXml);
XmlElement eventData = eventXmlDoc.DocumentElement;
// Validate event data
if (eventData != null)
{
// Get Work Item id from event data
int id = GetWorkItemId(eventData);
//EventLog.WriteEntry("TFS Services", String.Format("eventXmlDoc {0}", eventXmlDoc.InnerXml));
EventLog.WriteEntry("TFS Services", String.Format("Got Id {0}", id));
string changedby = GetWorkItemChangedBy(eventData);
EventLog.WriteEntry("TFS Services", String.Format("Got changedby {0}", changedby));
if (changedby != "TFSSERVICE")
{
//Add a 15 second delay in order to make sure all workitems are saved first before starting to update them
Thread.Sleep(15000);
EventLog.WriteEntry("TFS Services", "Calling UpdateWorkItemInternal");
UpdateWorkItemInternal(id);
}
}
}
private int GetWorkItemId(XmlElement eventData)
{
return Convert.ToInt32(eventData.SelectSingleNode("CoreFields/IntegerFields/Field[ReferenceName='System.Id']/NewValue").InnerText);
}
private string GetWorkItemChangedBy(XmlElement eventData)
{
return Convert.ToString(eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.ChangedBy']/NewValue").InnerText);
}
private static void UpdateWorkItemInternal(int id)
{
//Connect To TFS Server
EventLog.WriteEntry("TFS Services", string.Format("Updating Work Item {0}", id));
_Tfs = TeamFoundationServerFactory.GetServer("TeamServer");
_WorkItemStore = (WorkItemStore)_Tfs.GetService(typeof(WorkItemStore));
WorkItem workItem = _WorkItemStore.GetWorkItem(id);
switch ((string)workItem.Fields["System.WorkItemType"].Value)
{
case "Bug":
UpdateNotes(workItem);
break;
default:
break;
}
foreach (WorkItem item in _ChangedWorkItems)
{
if (item.IsDirty)
{
foreach (Field field in item.Fields)
{
if (!field.IsValid)
{
Console.Write("Not valid");
}
}
EventLog.WriteEntry("TFS Services", string.Format("Saving WorkItem: {0}", item.Id));
try
{
item.Save();
}
catch (Exception ex)
{
}
}
}
_ChangedWorkItems.Clear();
}
private static void UpdateNotes(WorkItem workItem)
{
Field notes = workitem.Fields["System.VSTS.Notes"];
if (notes != null)
{
notes = string.Format("{0} - {1}", workItem.ChangedDate, workItem.ChangedBy);
}
if (workItem.IsDirty)
{
if (!_ChangedWorkItems.Contains(workItem))
{
_ChangedWorkItems.Add(workItem);
}
}
}
}
这只是从我现有的代码中复制和粘贴的快速和肮脏的,所以仔细检查它以确保我没有引入错字。