All posts by Adam Prescott

I'm enthusiastic and passionate about creating intuitive, great-looking software. I strive to find the simplest solutions to complex problems, and I embrace agile principles and test-driven development.

WPF Combo Box validation

I’ve been working on a small WPF project that requires some business rule validation. I thought this would be relatively simple but proved to be slightly more complicated than expected. At the end of the day, I found two relatively simple ways to perform the validation.

The first is to simply bind ComboBox.Selected item to a property and do the validation in the set block.

    private MyDataObject _someData;
    public MyDataObject SomeData
            return _ someData;
            _ someData = value;
            if (value == null || string.IsNullOrEmpty(value.MyProperty))
                throw new ApplicationException("SomeData is required");

Then, in the XAML, you just need to hook it up to treat exceptions as validation errors.

        <Binding Path="SomeData" ElementName="Window">
                <ExceptionValidationRule />

The second method gives more flexibility but requires the creation of a custom ValidationRule class.

    public class MyCustomValidationRule : ValidationRule
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            if (value is MyDataObject)
                var myDataObj = (MyDataObject)value;
                if (myDataObj.CheckCustomBusinessRules())
                    return new ValidationResult(true, null);
            return new ValidationResult(false, "Invalid selection!");

And then you hook up the validation rules to use the new custom class.

        <Binding Path="SomeData" ElementName="Window">
                <local:PersonValidation />

(Note that the “local” prefix requires an additional namespace at the top of your XAML file, xmlns:local=”clr-namespace:MyNamespace”)

One last tip that threw me off for a bit is that I was missing x:Name=”Window” in my Window tag at the top of my XAML; this caused the ComboBox’s SelectedItem to not bind properly and the validation rules consequently didn’t work.


Mass find & replace in TFS using Powershell

One of the problems that seems to come up semi-frequently is, “We need to update all x files to have y!” The old solution to this was manually going through all x files and updating them to have y. However, this can be accomplished quickly and easily using Powershell.
Here’s an example. We had a number of VB6 project files whose BCO paths were set to use a mapped “O:” drive that no longer existed. Instead, these projects should be using a relative path. There were 100 or so of these projects that needed to be updated, and I was able to check them out from TFS and make the change to all of them in a matter of seconds by using the following script (sorry for the formatting!):

Get-ChildItem "C:\Code" -recurse | 
    Where-Object {$_.Extension -eq ".vbp"} | 
    ForEach-Object {Write-Host "  "$_.FullName; &amp; "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe" checkout "$($_.FullName)" | Out-Null; (Get-Content $_.FullName) | 
        ForEach-Object {$_ -replace "O:\\.*?\\BCO\\", "..\..\BCO\"} | 
            Set-Content $_.FullName -Force}

And another example. I needed to update the revision numbers of all projects in a sub-directory to be automatic. Here’s the same script modified to accomplish that. I’ve made this more re-usable by accepting parameter values from the command line.

# example usage: .\UpdateVersion.ps1 -path "C:\Code" -build "1.0.0.*"

# get param values
  [int] $build, 
  [string] $path, 
  [string] $root)

if ($build -eq $null)
    $build = Read-Host "Build number:"
if ($path -eq $null)
    $path = ".\"

# $root will be trimmed from start of directory string
# when checking for exceptions
if ($root -eq $null)
    $root = "c:\"

# $exceptionDirs will not have their versions updated
$exceptionDirs = "test"

Write-Host "Updated the following files:"

# recursively search $path for AssemblyInfo.cs
# if found, update version number &amp; save
Get-ChildItem $path -recurse | 
    Where-Object {$_.Name -eq "AssemblyInfo.cs"} | 
    Where-Object {$exceptionDirs -notcontains $_.Directory.ToString().ToUpper().TrimStart($root.ToUpper())} |
    ForEach-Object {Write-Host "  "$_.FullName; &amp; "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe" checkout "$($_.FullName)"; (Get-Content $_.FullName) | 
        ForEach-Object {$_ -replace "(?(\d+\.){3})\d+", "`${ver}$build"} | 
            Set-Content $_.FullName -Force}

❤ Powershell!

VS2010 Extensions

I just upgraded to VS2010 at work this week, and I feel like a kid in a candy store with all of the extensions available online. ( Here are some of the ones that I’ve already fallen in love with…

Team Foundation Server Power Tools April 2010:
TFPT.exe; PowerShell Cmdlets for VSTS; Windows Shell Extensions

PowerCommands for Visual Studio 2010:
Copy/paste classes & references; email code snippets; open containing folder from Solution Explorer

Collapse Selection in Solution Explorer:
Recursively collapse the selected node in Solution Explorer

Search Work Items for TFS 2010:
Search TFS work items from a menu bar textbox

SFTP Access with SharpSSH

A project that I was working on required the use of SFTP to transfer some files. I was surprised to find that there seemed to be no support for this anywhere in the .net Framework. After Googling around for a bit, I found a nice open source project called SharpSSH.

SharpSSH was surprisingly easy to use and worked great! I was able to SFTP a file in 4 lines of code:

SshTransferProtocolBase sshCp = new Sftp("", "ftp", "ftp123");
sshCp.Put("c:\\testdoc.txt", "test123.txt");

This was exactly what I was looking for: a simple, lightweight SFTP library. I added some exception handling and logging, removed my hard-coded values with user-defined settings, and called it a day!


freeSSHd (a free SFTP server)

Link TFS Work Items Programmatically

One of the things that’s bothered me with TFS is the need to manually link Sprint Backlog Items to Product Backlog Items. During sprint planning meetings, we use Excel to quickly create lots of sprint backlog items for everybody on the team, but then we need to go through and manually create links to related product backlog items that we use for release planning and release progress tracking.

I decided to do a little research and found that TFS work items can be linked programmatically by utilizing the Visual Studio SDK’s TeamFoundation libraries. I use a TFPT command-line wiql query to find potential link candidates, then parse work item titles for a common number than can be used to find related work items. I do another wiql query to search for the work item ID of the related product backlog item. If found, I attempt to create a link between the two work items.

Here’s the relevant code:

TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer("mytfs");
WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
WorkItem sbiWorkItem = store.GetWorkItem(sbiId);
    sbiWorkItem.Links.Add(new RelatedLink(pbiId));
    Console.WriteLine(string.Format("Linked SBI {0} to PBI {1}", sbiId, pbiId));
catch (Exception ex)
    // ignore "duplicate link" errors
    if (!ex.Message.StartsWith("TF26181"))
        Console.WriteLine("ex: " + ex.Message);

Visual Studio 2008 SDK v1.1