WPF ListBox Virtualization

Virtualization in WPF is amazing when you get it, annoying when you lose it.  I’m working on a form where the user can dynamically filter and sort a ListBox.  I’m using a DataTemplate to give a nice card-like view to each object, which makes it take up a  lot of space on the screen.  To fix this I used the WrapPanel as the ListBox’s ItemsPanel.


WrapPanel is not virtualized, I can’t find one that is and don’t have any time to write one myself.  So I came up with a work around to give the user a fixed number of column view using the standard panel for a ListBox.  This got me virtualization back.  Then I wanted to smoothly scroll so I turned ScrollViewer.CanContentScroll to false.  Smooth scrolling, no virtualization.  Because this box may have thousands of records in it, performance is much more important than smooth scrolling. 

The moral of the story is, if you’re working on something in WPF and performance is important and you might have a large dataset coming in.  Double check your changes to controls to make sure you’re maintaining virtualization.  If anybody has a good list of what disables virtualization (grouping, custom panels, smooth scrolling), I’d like to see it.

5 Replies to “WPF ListBox Virtualization”

  1. If ListBox is inside a vertically unconstrained control, your virtualization will dissapear because ListBox thinks it has unlimited amount of space for its rows. Example: put listbox inside vertical stack panel.

  2. I’m doing the exact same thing you are with a little personal application and found your post on this subject.

    Any chance you’ll release the code to your multi-column view you created?

  3. Unfortunately, some of the stuff I do is under NDA for clients, but the concept is simple. Have an ObservableCollection<ObservableCollection<YourItem>> and bind the list of lists to your ListBox. Then create two datatemplates, one for showing the list of items in each row as a ItemsControl or something similar, and the second to actually template the individual items.

    I wrote a class to abstract some logic that you could pass in a collection and a number of “columns” and it would split up a list for you into a list of lists automatically, but it’s certainly doable manually for small scenarios

  4. Hi Nick,

    I have used something similar you mentioned above i.e. Nested observable

    For example say
    I have an observable collection of ObservableCollection and Each day is in Turn is an ObservableCollection
    The way I have represented this in a horizontal Listbox of Day as Column which is Virtualized with VirtualizationMode set to Recycling (Call it a DayListBOX).
    Each Day i.e. column is another List box of appointments (call it a AppointmentListbox)

    Now I scroll to say 15th day and I delete and appointment from day 1 in the AppointmentListbox. The DayListBOX scrolls back to the 1st Day.

    I tried getting the Verticaloffset and the horizontaloffset of the DayListBOX and after deleting an appointment tried setting it back but doesn

Leave a Reply

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