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.