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.