Share via


How to: Define a Work Item Link Handler

You can create a Visual Studio Integration Extension that responds when the user creates or deletes a link between a UML model element and a work item. For example, when the user chooses to link a new work item to a model element, your code could initialize the fields of the work item from values in the model.

Set up a UML Extension Solution

This will allow you to develop handlers and then distribute them to other users. You need to set up two Visual Studio projects:

  • A class library project containing the code of the link handler.

  • A VSIX project, which acts as a container for installing the command. If you want, you can include other components in the same VSIX.

To set up the Visual Studio solution

  1. Create a class library project, either adding it to an existing VSIX solution, or creating a new solution.

    1. On the File menu, point to New and then click Project.

    2. Under Installed Templates, click Visual C# or Visual Basic, then in the middle column click Class Library.

    3. Set Solution to indicate whether you want to create a new solution or to add a component to a VSIX solution that you have already opened.

    4. Set the project Name and Location and click OK.

  2. Unless your solution already contains one, create a VSIX project.

    1. In Solution Explorer, right-click the solution, point to Add, and then click New Project.

    2. Under Installed Templates, expand Visual C# or Visual Basic, then click Extensibility. In the middle column, click VSIX Project.

  3. Set the VSIX project as the startup project of the solution.

    • In Solution Explorer, right-click the VSIX project and then click Set as StartUp project.
  4. In source.extension.vsixmanifest, under Content, add the class library project as a MEF Component.

    1. Open source.extension.vsixmanifest

    2. Click Add Content.

    3. At Select a content type, select MEF Component.

    4. At Select a source, click Project and select the name of your class library project.

  5. Click Select Editions and select the Visual Studio editions you want your extension to run on.

  6. Set the name and descriptive fields of the VSIX. Save the file.

Perform all of the following tasks in the class library project.

Project References

Add the following .NET assemblies to your project references:

Microsoft.TeamFoundation.WorkItemTracking.Client.dll

Microsoft.VisualStudio.TeamFoundation.WorkItemTracking.dll Microsoft.VisualStudio.Modeling.Sdk.10.0

Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml

Microsoft.VisualStudio.Uml.Interfaces

System.ComponentModel.Composition

System.Drawing - used by the sample code

If you cannot find one of these references under the .Net tab of the Add Reference dialog, use the Browse tab to find it in \Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\.

Import the Work Item Namespace

In your Visual Studio project References, add references to the following assemblies: 

  • Microsoft.TeamFoundation.WorkItemTracking.Client.dll

  • Microsoft.VisualStudio.TeamFoundation.WorkItemTracking.dll

In your program code, import the following namespaces:

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.TeamFoundation.WorkItemTracking;
using System.Linq;

Define the Linked Work Item Event Handler

Add a class file to the class library project, and set its contents as follows. Change the namespace and class names to whatever you prefer.

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.TeamFoundation.WorkItemTracking;
using System.Linq;


namespace WorkItems
{
  [Export(typeof(ILinkedWorkItemExtension))]
  public class MyWorkItemExtension : ILinkedWorkItemExtension
  {
    // Called before a new work item is edited by the user.
    // Use this to initialize work item fields from the model element.
    public void OnWorkItemCreated(System.Collections.Generic.IEnumerable<IElement> elementsToBeLinked, IWorkItemDocument workItemDocument)
    {
      INamedElement namedElement =
            elementsToBeLinked.First() as INamedElement;
      if (namedElement != null)
        workItemDocument.Item.Title = namedElement.Name;

    }

    // Called when any work item is linked to a model element.
    public void OnWorkItemLinked(System.Collections.Generic.IEnumerable<IElement> elements, string serverUri, int workItemId)
    {
      foreach (IElement element in elements)
        foreach (IShape shape in element.Shapes())
          shape.Color = System.Drawing.Color.Red;
    }

    // Called when a work item is unlinked from a model element.
    public void OnWorkItemRemoved(IElement element, string serverUri, int workItemId)
    {
      foreach (IShape shape in element.Shapes())
        shape.Color = System.Drawing.Color.White;
    }
  }
}

For test purposes, execute your link handler in debug mode.

  1. Press F5, or on the Debug menu, click Start Debugging.

    An experimental instance of Visual Studio starts.

    Troubleshooting: If a new Visual Studio does not start, ensure that the VSIX project is set as the Startup project of the solution.

  2. In the experimental Visual Studio, open or create a modeling project, and open or create a modeling diagram.

  3. Create a model element such as UML class, and set its name.

  4. Right-click the element and then click Create Work Item.

    • If the submenu shows Open Team Foundation Server Connection, click it and follow the dialogs to connect to a server. Then again right-click the model element and click Create Work Item.

    • If the submenu shows a list of work item types, click one.

      A new work item form opens.

  5. Verify that the title of the work item is the same as the model element, if you have used the sample code in the previous section. This demonstrates OnWorkItemCreated() has worked.

  6. Complete the form, save and close the work item.

  7. Verify that the work item is now colored red. This demonstrates OnWorkItemLinked() in the sample code.

    Troubleshooting: If the handler methods have not run, verify that:

    • The class library project is listed as a MEF component in the Content list in source.extensions.manifest in the VSIX project.

    • The correct Export attribute is attached to the handler class, and the class implements ILinkedWorkItemExtension.

    • The parameters of all Import and Export attributes are valid.

About the Work Item Handler Code

Listening for New Work Items

OnWorkItemCreated is called when the user chooses to create a new work item to be linked to the model elements. Your code can initialize the work item fields. The work item is then presented to the user, who can update the fields and the save the work item. The link to a model element is not created until the work item has been successfully saved.

  public void OnWorkItemCreated(
      IEnumerable<IElement> elementsToBeLinked,
      IWorkItemDocument workItem)
  {
    INamedElement namedElement = 
           elementsToBeLinked.First() as INamedElement;
    if (namedElement != null)
        workItem.Item.Title = namedElement.Name;
  }

OnWorkItemLinked is called just after a link is created. It is called whether the link is to a new work item or an existing item. It is called once for each work item.

public void OnWorkItemLinked
        (IEnumerable<IElement> elements, 
         string serverUri, // TFS server
         int workItemId)
{
  foreach (IElement element in elements)
    foreach (IShape shape in element.Shapes())
         shape.Color = System.Drawing.Color.Red;
}

Note

To make this example work, you must add a project reference to System.Drawing.dll, and import the namespace Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation. However, these additions are not required for other implementations of OnWorkItemLinked.

OnWorkItemRemoved is called once just before each work item link that is deleted. If a model element is deleted, all of its links will be removed.

public void OnWorkItemRemoved
         (IElement element, string serverUri, int workItemId)
{...}

Updating a work item

Using the Team Foundation namespaces, you can manipulate a work item.

To use the following example, add these .NET assemblies to your project's References:

  • Microsoft.TeamFoundation.Client.dll

  • Microsoft.TeamFoundation.WorkItemTracking.Client.dll

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
...
public void OnWorkItemLinked
        (IEnumerable<IElement> elements, 
         string serverUri, // TFS server
         int workItemId)
{
  TfsTeamProjectCollection tfs =
        TfsTeamProjectCollectionFactory
            .GetTeamProjectCollection(new Uri(serverUri));
  WorkItemStore workItemStore = new WorkItemStore(tfs);
  WorkItem item = workItemStore.GetWorkItem(workItemId);
  item.Open();
  item.Title = "something";
  item.Save();
} 

You can access the links as follows:

//Get:
string linkString = element.GetReference(ReferenceConstants.WorkItem);
// Set:
element.AddReference(ReferenceConstants.WorkItem, linkString, true);

The format of linkString is:

string.Format(@"%{0}\{1}#{1}${2}", tfServer, projectCollection, RepositoryGuid, workItem.Id);

where:

  • The URI for your server would be:

    http://tfServer:8080/tfs/projectCollection

    Case is important in projectCollection.

  • RepositoryGuid can be obtained from your TFS connection:

    TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory...;
    RepositoryGuid= tpc.InstanceId;
    

For more information about References, see How to: Attach Reference Strings to Model Elements.

See Also

Reference

Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore

Concepts

How to: Link from Model Elements to Work Items

How to: Attach Reference Strings to Model Elements

How to: Define and Install a Modeling Extension

Programming with the UML API