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.

Comments

  1. Concerned Citizen says:

    This sounds good but in actuality it’s like cutting your nose off to spite your face. You’re robbing Peter to pay Paul. Why would you want to create bugs to fix one? Overriding the HighlightBrushKey causes problems with the contents of your ListView. There are workarounds for that but the time spent fixing them would make the first fix not worth it…

  2. Scott says:

    If you have more specifics about what sort of problems you’ve encountered, I’d be very interested in hearing about them. With the changes that we made for our application, we were able to preserve all the functionality of combined ScrollViewer and ItemsControl with no additional bugs being reported.

  3. Concerned Citizen says:

    The way our application works, the contents are bound and use a data template. The data template includes a context menu. This change makes the context menu all black with black letters for the context menu items.

  4. Scott says:

    That explains the difference. Our application doesn’t have context menus defined in the data template. Any actions that need to be taken on an element within the list view are triggered by buttons, instead of context menus. What happens if you set the Background attribute of the list view to be transparent? Do you still get the same behavior from your context menus?

  5. Scott says:

    Sorry this solution isn’t working for you. Unless you have some flexibility in redefining the look-and-feel of your context menu, I’m not sure what options are available to you beyond returning to using ScrollViewer+ItemsControl.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.