Extending VSTS Work Item Tracking UI: Accessing work item UI elements and responding to events


VSTS work item tracking UI elements such as work item form, query document and result list are exposed for access by Addins and VSIP packages. This post helps to get jump start on how to access those elements and use the events for custom actions.


1) WorkItemTrackingExtensionPackage.zip: It is a VSIP package that demonstrates how to access all 3 work item UI objects (Work Item form, query form and result list) and show basic details on those documents. Contains readme.txt for additional details.

2) WorkItemInspector.zip: This is a VS Addin that demonstrates how to access work item form from an Addin and display all its fields in a grid. Jason created this sample

Creating an VS Addin or VSIP package with references to TFS assemblies

Ed Hintz has a great post with step-by-step instructions on how to create an AddIn with references to TFS Assmblies. Go over steps 1-3 in his post at http://blogs.msdn.com/edhintz/archive/2006/02/03/524312.aspx for addins. The assemblies you need for work item tracking are:


- Microsoft.TeamFoundation.Client

- Microsoft.VisualStudio.TeamFoundation.Client

- Microsoft.TeamFoundation.WorkItemTracking.Client

- Microsoft.VisualStudio.TeamFoundation.WorkItemTracking

For creating a VSIP package instead,

- Install VSIP from http://msdn.microsoft.com/vstudio/extend/default.aspx

- select File/New/Project from VS, and choose “Visual Studio Integration Package” under “Other Project Types”\Extensibility.

- In the Wizard, choose to create a menu item, under which you can write code to experiment with WIT documents.

Working with Document Service:

DocumentService is the public service for creating, getting, and showing Work Item Tracking VSIP documents.

Getting DocumentService from Addin: A reference to DocumentService can be obtained from DTE reference. For Addin project above, _applicationObject will point to DTE instance.

                        witDocumentService = (DocumentService)_applicationObject.DTE.GetObject("Microsoft.VisualStudio.TeamFoundation.WorkItemTracking.DocumentService");

Getting DocumentService from VSIP Package: If WIT package is loaded, doing a GetService from IServiceProvider (implemented by package itself) will return pointer to DocumentService

DocumentService docService = (DocumentService)serviceProvider.GetService(typeof(DocumentService));

Some selected methods/properties of DocumentService:




Finds the document for given canonicalId if it is loaded and returns IWorkItemTrackingDocument. dte.ActiveDocument.FullName can be used to get the canonicalId of the active document. LockToken parameter is an object that can be passed to make sure the document does not get unloaded until it is released. Make sure Document.Release is called with that LockToken object to let it unload after use.


Creates a new IWorkItemDocument for given project and work item type. To open new work item document window in VSTS, you need to pass the current server and the project name. See below on how to get active server. Alternatively, a WorkItem object can be created with some fields filled and can be passed to this method.


Once a IWorkItemDocument reference is obtained (such as in above method), this method shows the document in UI

CreateQuery and ShowQuery

Similar to CreateWorkItem & ShowWorkItem for queries.

CreateResults and ShowResults

Similar to CreateWorkItem & ShowWorkItem for results.

DocumentAdded and DocumentRemoved

Hook to these events to run custom code when documents are added or removed. Hook to IWorkItemTrackingDocument events (explained below) for each document’s save/open/close events.

Getting active (current) server and project from Team Explorer: For some operations such as CreateWorkItem, current server name is needed. This can be obtained from TeamFoundationServerExt object. Here is a post on how to do it: http://blogs.msdn.com/hippietim/archive/2006/03/29/563988.aspx . Alternatively, if you are in a VSIP package, you can obtain IVsTeamExplorer service using GetService to accomplish the same.

Getting Active Document

Name of active document can be obtained from DTE using _applicationObject.ActiveDocument.FullName property. Current document pointer can be obtained from DocumentService object using:

            IWorkItemTrackingDocument doc = docService.FindDocument(_applicationObject.ActiveDocument.FullName, this);


IWorkItemTrackingDocument is base interface for all 3 WIT documents, IWorkItemDocument (work item form), IQueryDocument (query form) and IResultsDocument (results form) and its reference can be casted to one of those WIT documents.

The properties and methods are straightforward to understand. Its Release method needs to be called after use if it was locked before with methods such as CreateWorkItem. The interface exposes events when loading, saving, closing etc, and it is useful for various scenarios such as enforcing additional custom validation or rules check when user is saving a workitem.

Methods/properties of each work item documents


       event WorkItemTrackingDocumentEventHandler Closing;

        event WorkItemTrackingDocumentEventHandler Closed;

        event WorkItemTrackingDocumentEventHandler Saving;

        event WorkItemTrackingDocumentEventHandler Saved;

        event WorkItemTrackingDocumentEventHandler Loading;

        event WorkItemTrackingDocumentEventHandler Loaded;

        event WorkItemTrackingDocumentEventHandler Reloaded;

        event WorkItemTrackingDocumentEventHandler SelectionChanged;

        void Save();

        void Load();

        void Reload();

        void Release(object o);

        bool IsNew

        bool IsLoaded

        bool IsDirty

        string CanonicalId

        int TokenCount

        string Domain

        string TeamProject

        string ArtifactType

        bool IsDisplayed

        TeamFoundationServer TeamFoundationServer


IWorkItemDocument : IWorkItemTrackingDocument


        WorkItem Item

        string InfobarText


IQueryDocument : IWorkItemTrackingDocument


        event QueryDocumentEventHandler FieldChanged;

        string QueryText

        string Name

        string Description

        Guid GUID

        QueryScope QueryScope

        string FilterExpression

  ResultOptions ResultOptions

        int[] SelectedItemIds



IResultsDocument : IWorkItemTrackingDocument


        int[] SelectedItemIds

        WorkItemCollection WorkItems

        IQueryDocument QueryDocument