1

Everybody says the default ItemsPanel for a ListBox is a VirtualizingStackPanel. I created a ListBox-derived class (call it MyListBox) and it defaults to StackPanel instead.

I mean I have to force the virtualization, for example this way:

const string itemsPanelTemplateString = @"
<ItemsPanelTemplate
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
<VirtualizingStackPanel/>
</ItemsPanelTemplate>";

MyListBox {
    this.ItemsPanel = (ItemsPanelTemplate)
        System.Windows.Markup.XamlReader.Load(itemsPanelTemplateString);
}

I could reprint here my class, but that's not the point. I would like to know general answer.

The class does not change predefined ListBox style, but it uses own ListBoxItem-derived class.

I am pretty sure there are some conditions for using virtualization, as my colleague said he saw respective ListBox code in the past. Unfortunately right now we don't have access to the debug versions of MS dll's.

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Jan Slodicka
  • 1,505
  • 1
  • 11
  • 14

4 Answers4

1

ListBox and controls derived from ListBox will have VirtualizedStackPanel as the ItemsPanel by default, unless user code changes it explicitely.

However, if your custom ListBox happens to derive directly from ItemsControl (as opossed to actually deriving from ListBox) then you will get StackPanel as the default ItemsPanel.

Could that be the case in your code? If not, please share your control code.

btlog
  • 4,760
  • 2
  • 29
  • 38
Stefan Wick MSFT
  • 13,600
  • 1
  • 32
  • 51
  • MyListBox derives from ListBox, MyListBoxItem derives from ListBoxItem. I know that you cited msdn documentation, but that statement is simply not true. a) My example proves that. b) ListBox code as shown by .Net Reflector should prove that, too. – Jan Slodicka Apr 11 '11 at 08:24
1

Solved. It was my bug:

When overriding ListBox.OnApplyTemplate() (for the purpose of time measurement), I forgot to call base.OnApplyTemplate(). Apparently the selection of the item panel is done there.

Dangerous bug because everything seemingly worked.

Thank you to all who tried to help.

Jan Slodicka
  • 1,505
  • 1
  • 11
  • 14
0

The default style for a ListBox does not assign the ItemsPanel template.

According to the internal code I can see in reflector OnApplyTemplate will assign a VirtualizingStackPanel to the internal ItemsHost if a ItemsPanel template is not supplied.

Perhaps including your class code might be a good idea after all.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • ItemsPanel was not supplied. (Right now it is set to VirtualizingStackPanel to force expected behavior.) I would include the class code, but its 900 lines. And twice as many if I include the code using that class. Never mind, I'll try to investigate that further and will report the result. – Jan Slodicka Apr 11 '11 at 08:47
0

You can find good recommendations on improving performance of the Listbox at http://blogs.msdn.com/b/slmperf/archive/2010/10/06/silverlight-for-windows-phone-7-listbox-scroll-performance.aspx

THer's also a good alternative documented at http://blogs.msdn.com/b/delay/archive/2010/09/08/never-do-today-what-you-can-put-off-till-tomorrow-deferredloadlistbox-and-stackpanel-help-windows-phone-7-lists-scroll-smoothly-and-consistently.aspx

Another thing to note (apparently) is that you'll also only get virtualization if the collection you're binding to implements IList.

Matt Lacey
  • 65,560
  • 11
  • 91
  • 143
  • That last sentence isn't entirely accurate. If you binding anything less than an IList (ICollection or IEnumerable) then an `ItemsControl` will just suck the whole collection into its own internal implementation of `IList`. From there you will still get the benefits of UI elements being virtualized. However someone using say a `IEnumerable` provided by a function utalizing `yield return` might be surprised by all items generated by the function being full consumed right at the outset. – AnthonyWJones Apr 08 '11 at 20:48
  • In this concrete example MyListBox binds to ObservableCollection. – Jan Slodicka Apr 11 '11 at 08:33