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

Summary:

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.

Samples:

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 https://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 https://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:

Method/Property

Description

FindDocument

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.

CreateWorkItem

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.

ShowWorkItem

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: https://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

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

IWorkItemTrackingDocument:

       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

        

WorkItemTrackingExtensionPackageSample.zip

Comments

  • Anonymous
    July 10, 2006
    Eric Lee on be careful of proxy settings when using the Team Foundation Server Object Model, KPI and...

  • Anonymous
    July 10, 2006
    Attaching here Jason's sample on accessing WIT UI elements from Addin. For details on the sample, see...

  • Anonymous
    October 12, 2006
    Overview : If you have used links in work item tracking, you might have wondered if you could add your

  • Anonymous
    March 08, 2007
    The comment has been removed

  • Anonymous
    July 05, 2007
    What is custom control feature? Now you can show your own controls in work item form. See for http://blogs.msdn.com/narend/archive/2006/09/27/773025.aspx

  • Anonymous
    July 24, 2007
    Recently few asking me about how to implement custom validation rules in a work item form. Our rules

  • Anonymous
    July 24, 2007
    Recently few asking me about how to implement custom validation rules in a work item form. Our rules

  • Anonymous
    September 27, 2007
    Few customers wanted to add a menu to context menu of workitems in result list. It seems like a great

  • Anonymous
    November 15, 2009
    What is Type of querybuilder? is it a designer or doc? I wanna operating querybuilder UI by get column's value than update its value by expand group alias to single item. This is workaround for our team's TFS forbiden the function with query workitem by group:(.