ListBox not Virtualizing

2019-05-19 23:57发布

问题:

I have a ListBox which is not virtualizing. I am obviously missing something, but cannot find it.

It's actually a ListBox within a ListBox. The outer ListBox has an ItemTemplate which contains an Expander. The Expander is used to display a group of items. The content of the Expander is the second ListBox which displays the items. The ItemTemplate on the second ListBox is bound to the actual Item to display. The ViewModel class for my items has a number of properties which do not initialize data until the property Get is called. However, WPF is walking through every item and causing initialization logic, which I'm trying to avoid.

I discovered that using the ListCollectionView.GroupDescription causes a ListBox to not Virtualize. Now I am handling my own grouping in the ViewModel. My outer ListBox is bound to an ObservableCollection(ItemGroupViewModel), where ItemGroupViewModel has a GroupName and a list of Items. The second ListBox is bound to the Items in the ItemGroupViewModel. This did not fix the problem. I also checked VirtualizingStackPanel.GetIsVirtualizing() while debugging and it returns true, but WPF is still walking through every item. I've double checked to ensure my grouping logic does not fire off the data initialization logic in each item, which I'm trying to avoid.

I thought the IsSharedSizeScope could cause the ListBox to render all items in order to determine column sizing. So I turned SharedSizeScope off. Still no virtualization.

What am I missing?

回答1:

It is not virtualizing because it is inside an expander, the expander's template is a headeredcontentcontrol (as far as I remember), and it's template contains a stackpanel.

Contents of stackpanel can never have alignement stretch in the direction it is stacking, so your listbox will always have all the room it asks for, and then you get no virtualization. Your inner listbox won't get any verticalscrollbar either.

You have one solution (at least :)

1: Set maxheight on your inner listbox - probably the easiest.

Hope it helps :)