Printer Friendly Version      Send     
Click to Rate and Give Feedback
Related Articles
We introduce you to the benefits of building composite applications with the Composite Application Guidance for WPF from Microsoft patterns & practices.

By Glenn Block (September 2008)
ADO.NET Data Services provide Web-accessible endpoints that allow you to filter, sort, shape, and page data without having to build that functionality yourself.

By Shawn Wildermuth (September 2008)
See how routed events and routed commands in Windows Presentation Foundation form the basis for communication between the parts of your UI.

By Brian Noyes (September 2008)
Technology changes at a lightening-fast pace. This month Howard Dierking considers how the rapid changes affect developer priorities and magazine focus.

By Howard Dierking (September 2008)
More ...
Articles by this Author
Use the Team Foundation Server EventService to create and manage event subscriptions or create a Web service to receive and process events.

By Brian A. Randell (May 2008)
Learn how to add check-in notes and check-in policy support to a Word add-in, in this fifth and final installment of an ongoing discussion.

By Brian A. Randell (Launch 2008)
Team Foundation Server provides APIs that let you create check-in notes (categorized string data) and custom check-in policy implementations. These features combine to give project administrators better control over the group development process.

By Brian A. Randell (November 2007)
Add support for work items to the Team Foundation Server version control add-in.

By Brian A. Randell (September 2007)
Here Brian Randell presents everything you need to know to get started with Visual Studio 2005 Team Edition for Database Professionals.

By Brian A. Randell (February 2007)
In this new column, Brian Randell begins his long look at how to extend and enhance Visual Studio Team System.

By Brian A. Randell (January 2007)
The Express Editions of Visual Basic and SQL Server 2005 have lots of the features of the full-sized versions, but with a lot less of the overhead. Professional developer features such as full IntelliSense support, local debugger, Add Web Reference, and the improved Visual Data Tools will all be available in the Express products, so you don't have to leave your favorite features behind. In this article the author introduces you to these express editions and builds a sample app to get you started.

By Brian A. Randell (September 2004)
Microsoft is introducing a new suite of tools (code-named "Whitehorse") that will make it easier for you to design and implement systems that conform to a service-oriented architecture. Two of these tools -- the SOA Design Suite and the Class Designer -- support the graphical design of systems and components with support for code generation and support for bi-directional synchronization which lets you ensure that your diagram always represents your system design. This article introduces these tools and shows you how they'll improve your design and development efforts.

By Brian A. Randell and Rockford Lhotka (July 2004)
More ...
Popular Articles
See how to build a document-level Visual Studio Tools for Office customization and integrate it with a content type in SharePoint.

By Steve Fox (May 2008)
Chris Tavares explains how the ASP.NET MVC Framework's Model View Controller pattern helps you build flexible, easily tested Web applications.

By Chris Tavares (March 2008)
In this excerpt from his upcoming book, Laurence Moroney explains the basics of Silverlight animation and the animation tools available in Expression Blend.

By Lawrence Moroney (August 2008)
Microsoft Robotics Studio is not just for playing with robots. It also allows you to build service-based applications for a wide range of hardware devices.

By Sara Morgan (June 2008)
More ...
Read the Blog
SQL Server 2008 supports a new data type, HierarchyID, that helps solve some of the problems in modeling and querying hier­archical information. In the September 2008 issue of MSDN Magazine, Kent Tegels introduces you to the ...
Read more!
Many people using SharePoint technologies don't realize that there is auditing support built directly into the Windows SharePoint Services (WSS) 3.0 platform. In the September 2008 issue of MSDN Magazine, Ted Pattison walks you through a ...
Read more!
The September 2008 issue of MSDN Magazine is now available online. Here's what's in the issue: Hierarchy ID: Model ...
Read more!
Silverlight 2 features a rich and robust control model that is the basis for the controls included in the platform and for third-party control packages. You can also use this control model to build controls of your own. In the August 2008 issue of MSDN Magazine, Jeff Prosise describes how to ...
Read more!
In the August 2008 issue of MSDN Magazine, Matt Milner covers several topics regarding development with Windows Workflow Foundation, some that are intended to address specific reader questions, such as how to safely share a persistence database ...
Read more!
LINQ is a powerful tool enabling quick filtering data based on a standard query language. It can tear through a structured set of data using a simple and straightforward syntax. In the August 2008 issue of MSDN Magazine, Jared Parsons demonstrates a ...
Read more!
More ...
Team System
Work Item Tracking
Brian A. Randell

Code download available at: TeamSystem2007_04.exe (179 KB)
Browse the Code Online
In my previous column, I started to describe how you can build a source-code control add-in for Microsoft® Word 2003 using the APIs exposed in Team System. If you examine the check-in dialog exposed by Team Explorer in Visual Studio® 2005, you'll notice that the integrated check-in experience is quite rich. Not only can you check in source files, but you can also associate your check-in with work items, add check-in notes, and validate your check-in against policy. Figure 1 shows the standard check-in dialog with the Work Items option selected.
Figure 1 Team Explorer Integrated Check-In Dialog (Click the image for a larger view)
This is deceptively simple on the surface-in reality, this part of the check-in experience exposes a great number of work item features. For example, you can change the query used to display the work item list. You can drill down into a particular work item and manipulate it using the standard work item UI by double-clicking on it. And you can perform a check-in action, which you use to either associate the work item with the check-in's changeset or perform another action, such as marking the work item as complete.
Before you can implement these features in the add-in, you'll need a good understanding of the work item API. In this column, I'll explain how to build a simple Work Item Explorer (see Figure 2). This sample demonstrates the core operations needed to add work item support to the add-in. Due to space constraints, I'll only cover the core code needed to access the work item services of Visual Studio 2005 Team Foundation Server. I will not detail the sample's Windows® Forms-related code. (All the code is, however, provided in the download.) In the next installment of the Team System column, I'll show you how to add work item support to the add-in.
Figure 2 Simple Work Item Explorer (Click the image for a larger view)

Team Foundation Servers, Team Projects, and Work Items
The work item tracking subsystem is a core feature of a Team Foundation Server installation. In order to use work items, you need at least one team project, which you create using the New Team Project wizard. When using this wizard, you specify the process template to use (a blueprint that describes the structure your team project will be based upon).
Of particular interest to this discussion, the process template you choose defines the default types of work items your team project will initially support. You can choose to customize the existing work item types or add your own. Work items provide a way for your team members to track just about anything related to the team project, including, but not limited to, bugs and tasks.
A default Team Foundation Server installation includes two process templates: Microsoft Solutions Framework for Agile Software Development version 4.0 (MSF Agile for short), and MSF for CMMI Process Improvement version 4.0 (MSF CMMI for short). Figure 3 provides an overview of the default types of work items, what each is for, and with which templates each is included.
Each work item is composed of a set of fields. Team Foundation Server scopes fields to the entire server installation. You can create your own custom process template and thus your own custom work items either from scratch or by modifying the templates provided by Microsoft. When defining your own custom work items, you can also define custom field definitions. This, however, is a discussion for another article.

Getting Connected
The add-in currently connects to the Team Foundation Server installation and its version control service via the Connect method in the tfsvcUtil class. In addition, it uses a custom Windows Forms dialog to get the server connection string from the user. You can use that same code with a few slight modifications to include a connection to the work item tracking (WIT) store. First, you need to add a reference to the Microsoft.TeamFoundation.WorkItemTracking.Client.dll assembly. Then, in the tfsvcUtil class, you need add the following Imports statement:
Imports Microsoft.TeamFoundation.WorkItem-Tracking.Client
You must also provide a class-level variable defined to hold a reference to the WIT store:
Private m_tfsWIT As WorkItemStore
And finally, you need to add an additional line of code to the Connect method so it can connect to the WIT store (see Figure 4).
Assuming a valid TeamFoundationServer reference exists, all it takes to connect to the work item store is to call the TeamFoundationServer's GetService method and pass the type object for the WorkItemStore. If you dig deeper into the Team Foundation Server APIs, you'll discover the DomainProjectPicker class-a hidden gem in the Proxy namespace within the Microsoft.TeamFoundation.dll assembly. This class exposes a GUI that lets you define Team Foundation Server connections and optionally access team projects defined on a server. The sample application uses this class rather than the aforementioned code. The sample app needs references to the following Team Foundation Server assemblies to perform its tasks:
  • Microsoft.TeamFoundation.dll
  • Microsoft.TeamFoundation.Client.dll
  • Microsoft.TeamFoundation.Common.Library.dll
  • Microsoft.TeamFoundation.WorkItemTracking.Client.dll
  • Microsoft.TeamFoundation.WorkItemTracking.Controls.dll
The main form (frmMain.vb) of the sample application has six buttons, a combobox to list the selected team projects, a combobox to list the available work item types for the active team project, and a few labels to provide status information. You need to add the following Imports statements to the top of frmMain.vb:
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.Common
Imports Microsoft.TeamFoundation.Proxy
Imports Microsoft.TeamFoundation.Server
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
You must also add code to the click event handler in the Pick Team Foundation Server button, as shown in Figure 5 (note that the GUI management-related code has been left out for space purposes). This code displays the default Connect to Team Foundation Server dialog. The constructor of the DomainProjectPicker class provides an enumeration to control the style of the dialog. For example, you can choose to show the dialog with team project selection turned off. However, for this sample the default behavior is what you want. Figure 6 displays the results of the call to ShowDialog using the default constructor.
Figure 6 Connect Dialog Box 
When you click the Servers button, the dialog displays the built-in Add/Remove Team Foundation Server dialog. If you select one or more team projects and then click OK, the code binds the list of selected projects to the Team projects combobox control.

Accessing the WIT Store
Once you have a valid connection to the server, you can connect to the WIT store. In the click event handler of the Connect to Work Item Store button, you need to use the GetService method as discussed earlier to connect to the WIT store. Once connected, the code initializes a class-level Project reference using the currently selected team project name:
If mtfs IsNot Nothing Then
  mwis = CType(mtfs.GetService( _
    GetType(WorkItemStore)), WorkItemStore)
End If

mprj = mwis.Projects.Item(Me.cboTeamProjects.Text)
Once you have a connection to the WIT store, you can get information from the server. The private method UpdateInfoData, shown in Figure 7, performs this task and displays the data on the main form. The code first gets the selected project's list of work item types as an array of WorkItemTypes objects. It binds the array to the Type combobox, and then the code uses the WIT store's FieldDefinitions collection to get a count of the server's field definitions. Next, the code retrieves the count of stored queries, both public and private, available for the identity connecting to the server. Finally, the code constructs a dynamic Work Item Query Language (WIQL) query to get a list of work items available to the identity connecting. (More details on WIQL in a moment.) Note that the code gets the list of field definitions and the work item count via the WIT store reference, whereas it uses the active team project reference to retrieve the work item types and stored queries.
WIQL is a SQL-like language. Full syntax reference is available online at msdn2.microsoft.com/bb130155.aspx. You can execute WIQL queries either as a dynamic WIQL statement or from a stored query. You can publish queries to your Team Foundation Server, making them available as public queries for your entire team or as private queries for your use only.
A valid query returns a collection of WorkItems. The WIT only returns those work items that match the query request and are visible to the identity executing the query based upon any security restrictions. Note is that the WIT does not throw an exception if the resultset is restricted due to security. Each WorkItem type has a collection of Field objects; each field in turn maps to a FieldDefinition object that provides the metadata for that particular field.
Constructing a valid WIQL query requires a valid list of field names using either the field name or its reference name. The field name is the friendly version and, when composed of multiple words, usually has spaces. When used in a WIQL query, a field name with spaces needs to be enclosed in square brackets. The reference name is a fully qualified name of the field that resembles the format used for .NET types. For example, a work item's Title uses the friendly name of Title and the reference name of System.Title. As another example, the Integration Build field's name is Integration Build, and its reference name is Microsoft.VSTS.Build.IntegrationBuild. Its label on the CMMI templates Change Request work item form is Integrated In. You can examine all the field definitions for a particular server accessing the FieldDefinitions of a valid WorkItemStore reference. If you run the sample application and click the Show Fields List, you can view a list of all the fields defined and drill down into each item. You could use this information to help you construct WIQL queries or even build your own query-build UI.

Working with Queries
Each of the two process templates included in the default Team Foundation Server installation contains a set of predefined WIQL queries. The MSF Agile template includes 11, while the MSF CMMI template includes 16. You access stored queries on a per-project basis. Clicking the Show Stored Queries button in the sample application loads a form listing all the stored queries for the active team project. A listbox on the form displays all the stored queries by name. Double-clicking on a query will open a detail form similar to the one shown in Figure 8. If you examine the queries provided by Microsoft, you'll see that they use the reference names when referring to work item fields.
Figure 8 Stored Query Details for the All Tasks Query (Click the image for a larger view)
The detail form has two buttons: one that executes the query and returns the results in a grid and one that returns the results in a list view. The WIT API supports numerous ways to execute a WIQL query. The detail form shown in Figure 8 uses two different techniques to execute the query. If you click the Execute Query (Grid) button, the code preps the WIQL statement and passes it to the frmWIList that actually executes the query. When you click the Execute Query (List) button, the query is prepared differently and executed using the Query method of the stored query's project's store reference (see Figure 9).
Both pieces of code prepare the WIQL by checking for a predefined query macro: @project. (Any string in a WIQL statement that is prefixed with an @ sign is considered to be a macro.) The WIT plumbing automatically expands certain built-in macros, such as @today. Your own macros and the @project macro require manual substitution.
Depending on how you execute the query, you can have the WIT API perform macro substitution or you can do it yourself. The code in btnExecuteGrid performs simple manual substitution looking only for the @project macro. However, btnExecuteList lets the WIT API do the heavy lifting. For production code, using the API is recommended because, with the substitution approach, you might inadvertently do an incorrect substitution (such as if you were substituting for @project, but there was an occurrence of a superstring, such as @projected).
If you look at the results of each button click and the APIs used, you'll see that the results you're looking for often force you to go down a particular path. In the sample application, the grid detail form uses a WorkItemResultGrid control (more on this in just a bit) that only supports a WIQL string as input limiting the API choices. The list view, on the other hand, uses standard data binding to hook the WorkItemCollection to a standard Windows Forms ListBox control. Still, the end result is the same-executing the query returns a collection of WorkItem objects.

Presenting and Editing Work Items
If you can execute a WIQL query-either dynamically or from a stored query-you have the ability to view and manipulate work items using the work item object model. At some point, however, you might need to present a UI so the user can enter, edit, or view work item information. In fact, if you perform a check-in using the Team Explorer integrated check-in experience, you'll find that double-clicking on a work item brings up the standard work item editor. This is exactly the feature you want to have in the add-in that you're building.
Microsoft has exposed the main work item experience via user controls within the Microsoft.TeamFoundation.WorkItemTracking.Controls.dll assembly. The sample application uses three of the controls: WorkItemResultGrid (which is visible when clicking the btnExecuteGrid button on the frmStoredQueryDetails.vb form), PickWorkItemsControl (which lets you execute stored queries and searches), and WorkItemFormControl (which is visible when you double-click on a work item from the grid view or list view forms). The WorkItemFormControl control is shown in Figure 10.
Figure 10 WorkItemFormControl (Click the image for a larger view)
These three controls do all the heavy lifting when it comes to searching, viewing, and editing work items. While you can add the controls to your toolbox, the sample application sets up the controls dynamically. There isn't any real design-time experience. The sample application uses the PickWorkItemsControl when you click the Search for Work Items button on the main form.
The control needs a reference to a valid WIT store object and a reference to the active project. From there it does all the hard work. The sample form that hosts the control hooks the control's PickWorkItemsListViewDoubleClicked event to show the work item using the WorkItemFormControl, as shown in Figure 10.
WorkItemFormControl exposes an Item property where you set the active work item that should be displayed. You have full access to each field and its dirty state. You can also reset the work item's values to their original queried values by using the Reset method. But keep in mind that it is up to you to implement your own save and cancel logic.
Figure 11 provides the relevant bits of code necessary to do just that. Note that if the user cancels the editing experience via the Cancel button or by using the window adornments, the code resets the work item. This is an important point if you're using a collection of WorkItems. The control takes changes in the UI and transfers them to the work item immediately. If you don't reset, the work item is dirty, and if it is reopened by the user, it will still have that information.
When performing a save operation, you use the IsDirty and IsValid properties to determine if a save is necessary and possible. If the work item is not valid, you use the work item's Validate method to retrieve a list of the invalid fields. This gives you an opportunity to either correct the errors in code or return the user to the UI (which is what the code in Figure 11 does). If the work item is valid, you save the changes to the object and back to the Team Foundation Server using the Save method.
Finally, if you want to be able to create new work items in your application, you need one more piece of data. As part of the code shown earlier in Figure 7, a combobox on the main form is loaded with a list of work items supported by the active project. The combobox control lists the Name of each work item. This is all you really need to spin a work item and open the UI. The following code shows what you need to do:
Dim WIT As String = Me.cboWIType.Text
If WIT IsNot Nothing AndAlso WIT <> String.Empty Then
  Dim wi As WorkItem = mprj.WorkItemTypes(WIT).NewWorkItem()

  Using f As New frmAWorkItem(wi)
    f.ShowDialog(Me)
  End Using
End If
Basically, you pass the string name of the work item type to the WorkItemTypes collection object and call its NewWorkItem method. The code then passes the new work item instance to the frmAWorkItem object's constructor, which binds the new work item to the WorkItemForm control.

Conclusion
The Work Item Tracking subsystem offered by Team Foundation Server exposes a rich object model for integration with your own solutions. Accessing work item information from any application only requires a few lines of code. In addition, when building an application, you can let the built-in controls do the heavy lifting to provide a rich and consistent interface. In the next column, I'll show you how to integrate work item support into the add-in that I started in the previous column.

Send your questions and comments to  mmvsts@microsoft.com.


Brian A. Randell is a senior consultant with MCW Technologies LLC. Brian spends his time speaking, teaching, and writing about Microsoft technologies. He is the author of Pluralsight's Applied Team System course and is a Microsoft MVP. Contact Brian via his blog at mcwtech.com/cs/blogs/brianr.

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.
Page view tracker