New MSBuild 4.0 Features

My current assignment has me working with the application build again.  MSBuild 4.0 got a number of new features which I’m only now getting to take advantage of.  The coolest one so far is the extensible task factory.  It lets you define custom MSBuild tasks right in the project file, instead of having to create a separate DLL for them.  Andrew Arnott wrote a custom factory that lets you define custom MSBuild tasks using PowerShell.  Because we’re using PowerShell for UI automation testing of our application, we’ll soon be able to integrate those tests into our build system.

Another feature I just learned about is conditional constructs.  They provide functionality equivalent to a case statement you might see in other languages. It’s much more flexible than the Condition attribute available on most MSBuild tasks.

ScrollViewer+ItemsControl vs. ListView

One of my most recent tasks at work was determining the cause of slow performance in one part of an application and coming up with a fix (if possible).  We tracked the source of the problem down to a use of ItemsControl inside a ScrollViewer.  Because the ItemsControl instance was trying to display hundreds of complex items, it took a noticeably long time to load.  This turns out to be a known issue, with a few possible solutions.  Simply changing the ItemsPanelTemplate of the ItemsControl instance to contain a VirtualizingStackPanel didn’t fix our performance problem.

What did resolve our performance issue was replacing the ScrollViewer and ItemsControl combination with a ListView.  The list of what we changed includes:

  • Giving the ListView the same name as the ItemsControl.
  • Giving the ListView the same ItemsSource as the ItemsControl.
  • Update the ItemsPanelTemplate of the ListView to use VirtualizingStackPanel.
  • Set HorizontalScrollBarVisibility to “Disabled”.
  • Bound the Visibility property of the ListView to a Converter.
  • Update the ItemContainerStyle with a ListViewItem style that sets the HighlightBrushKey and ControlBrushKey to be transparent.

Note: The last of those steps does override those styles for the entire application, so it may be best to skip it unless it doesn’t negatively impact the look-and-feel of the rest of your application.

The changes we made reduced the load time from around 20 seconds down to less than 2 seconds for 400 items.

The tradeoff in moving to a ListView (with VirtualizingStackPanel) from ScrollViewer+ItemsControl is scrolling speed.  Scrolling through 400 items does go more slowly, but it’s preferable to waiting as long as we did just to see the data.