Mathias Olausson [MVP] :: thoughts on Visual Studio ALM

Browse items in TFS Version Control programmatically, reposted

I got a comment a while back that some articles on my old blog has broken links so I’m fixing that by reposting the updated articles here. This one is about using the TFS API to open a browser dialog from TFS 2008. The code still works with 2010 but there might be a better way to do that now but for now this is a working solution.

Ever wanted to use the TFS API to pull up a dialog to let a user browse the version control repository and select a file or a folder? Unfortunately it turns out there is no function to do so. Or atleast, no obvious way...

With pointers from Philip Kelley at Microsoft I learnt that inside the Microsoft.TeamFoundation.VersionControl.Controls assembly there's a private class called DialogChooseItem that displays the following dialog:

ItemBrowser

In order to use that dialog we'll have to invoke by using .NET reflection. The constructor can take either just the TFS to connect to (start at the root of the version control tree) or the folder and file to navigate to when the dialog is shown.

The key code to invoke the dialog is the following (based on Visual Studio 2008 SP1 and TFS 2008 SP1):

VersionControlServer versionControlServer = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
Assembly controlsAssembly = Assembly.GetAssembly(typeof(Microsoft.TeamFoundation.VersionControl.Controls.ControlAddItemsExclude)); 
Type vcChooseItemDialogType = controlsAssembly.GetType("Microsoft.TeamFoundation.VersionControl.Controls.DialogChooseItem");
ConstructorInfo ci = vcChooseItemDialogType.GetConstructor(
                   BindingFlags.Instance | BindingFlags.NonPublic,
                   null,
                   new Type[] { typeof(VersionControlServer) },
                   null);
_chooseItemDialog = (Form)ci.Invoke(new object[] { versionControlServer });
_chooseItemDialog.ShowDialog();
 this.DialogResult = _chooseItemDialog.DialogResult;

To get to the selected item access the SelectedItem property (again using .NET reflection):

_selectItemProperty = vcChooseItemDialogType.GetProperty("SelectedItem", BindingFlags.Instance | BindingFlags.NonPublic);
Item selectedItem = (Item)_selectItemProperty.GetValue(_chooseItemDialog, null);
selectedItem.ServerItem;

That's it. With some simple .NET reflection magic we can now use the internal item brower dialog.

The complete sample can be downloaded here: ItemBrowser.zip (15,63 KB)

Update: a solution for Visual Studio 2010 cam be downloaded here: ItemBrowser-vs2010.zip (17,67 KB). 

Disclamer: the DialogChooseItem is an internal unsupported implementation. It may change at any time so if you use it your're on your own.